题意:
交互题,已知一个有一个 t + c t + c t+c 个点 的 P P P 型的有向图(还是看图吧),其中环部分点数为 c c c,剩余部分点数为 t t t,现在起点处为入度为 0 0 0 的那个点,终点处为环与直线部分的交点,现在有编号 0 − 9 0-9 0−9 共 10 10 10 个小朋友在起点处,每次可以选择其中若干个小朋友同时移动一步,然后评测机返回 k k k 组小朋友,同一组代表在同个位置,试用不超过 q q q 次询问让所有人到达终点。 ( 1 ≤ t , c , t + c ≤ 1000 , q = 3 t + 3 c ) (1 \leq t, c, t + c\leq 1000, q = 3t + 3c) (1≤t,c,t+c≤1000,q=3t+3c)
链接:
https://codeforces.com/contest/1137/problem/D
解题思路:
经典的用 f l o y d floyd floyd 判圈法来判定链表上的环,具体做法为设置一快、一慢两个指针,快指针每次移动 2 2 2 步,慢指针每次移动 1 1 1 步,则两者必然在环上某一点相遇,相遇时慢指针仍未遍历完环,若慢指针遍历过一次环,则必有快指针遍历过两次,期间一定相遇,则此过程慢指针移动次数小于 t + c t + c t+c,询问数小于 2 t + 2 c 2t + 2c 2t+2c。
设相遇时慢指针遍历了环上 x x x 个点,则有 2 ( t + x ) = t + x + k c 2(t + x) = t + x + kc 2(t+x)=t+x+kc,得到 − x + k c = t -x + kc = t −x+kc=t,即 − x ≡ t ( m o d c ) -x \equiv t \pmod{c} −x≡t(modc),此时让所有人同时移动,最后必然在 t t t 次后于终点处相遇。故总询问次数满足小于 3 t + 3 c 3t + 3c 3t+3c。
参考代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e6 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int read(){
int k; cin >> k; char s[233];
for(int i = 0; i < k; ++i) cin >> s;
return k;
}
int main(){
ios::sync_with_stdio(0); cin.tie(0);
while(1){
cout << "next 0" << endl; read();
cout << "next 0 1" << endl;
if(read() == 2) break;
}
while(1){
cout << "next 0 1 2 3 4 5 6 7 8 9" << endl;
if(read() == 1) break;
}
cout << "done" << endl;
return 0;
}