大江东去,浪淘尽,千古风流人物。故垒西边,人道是,三国周郎赤壁。乱石穿空,惊涛拍岸,卷起千堆雪。江山如画,一时多少豪杰。遥想公瑾当年,小乔初嫁了,雄姿英发。羽扇纶巾,谈笑间,樯橹灰飞烟灭。故国神游,多情应笑我,早生华发。人生如梦,一尊还酹江月。

CF1137D题解

神仙交互题

记得以前听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=2*t+2*x+t=2*x+3*t<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;
}
posted @ 2019-11-01 20:30  White_star  阅读(204)  评论(0编辑  收藏  举报
}