神仙交互题
记得以前听lch神仙讲过,不过当时还没做过这道题
题意(来自yyb神仙的翻译):
有一张图是由一个长度为t的链和一个大小为c的环中间连上一条边组成的。
假如这条边连接的是链的右端点,和环上的T点。
令链的左端点是S。
现在在S处有10个棋子,编号0−9,每次你可以让任意数量的棋子向出边方向走一步,交互库会返回若干个集合,每一个集合内的棋子都在同一个位置上,并且这个位置上的所有棋子都在这个集合中。
现在你既不知道t也不知道c。你需要使用不超过3(t+c)次操作使得所有棋子都移动到T位置上并且返回交互库
官方题解翻译......(手动翻译,不是机翻)
棋子的数量在这里是迷惑你的,其实只需要三个棋子就可以解决问题
我们把移动速度快的棋子叫做fast,慢的叫slow,slow每走一步,fast走两步,当他们相遇时停止
显然,slow无法在环上走完完整的一圈,因为slow每走1圈,fast走两圈,一定会被fast追上
故他们相遇时行走的距离\(slow=t+x\),\(fast=t+x+k*c\),且\(fast=2*slow\)
解得\(x≡-t(mod c)\)
所以再走t步就能到达终点了,但我们不知道t是多少,注意到留在原点的棋子离终点距离刚好为t,故让所有棋子同时走,相遇时就都到达了终点
询问次数q=2t+2x+t=2x+3t<3*(x+t),故可以通过此题
#include<bits/stdc++.h> using namespace std; #define go(i,a,b) for(int i=a;i<=b;++i) #define com(i,a,b) for(int i=a;i>=b;--i) #define mem(a,b) memset(a,b,sizeof(a)) #define fo(i,a) for(int i=0;i<a;++i) #define il inline string s; il int read(){ int x;scanf("%d",&x); go(i,1,x) cin>>s; return x; } int main(){ //freopen("input.txt","r",stdin); while(23333){ puts("next 0 1"); cout.flush(); read(); puts("next 0"); cout.flush(); if(read()==2) break; } while(23333){ puts("next 2 3 0 1 4 5 6 7 8 9"); cout.flush(); if(read()==1) break; } puts("done"); cout.flush(); return 0; }