CF1137D题解

吃可爱长大的小学妹 提交于 2019-12-03 05:10:02

神仙交互题

记得以前听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;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!