CF835E The penguin's game 題解
阿新 • • 發佈:2022-03-27
Solution
同一型別的套路題見了這麼多了結果還是做不出來,我麻了。
可以發現我們可以枚舉出哪些二進位制位這兩個位置不一樣,然後我們求出一種一個位置另外一個就可以直接通過異或求出。考慮怎麼求出一個,首先我們肯定可以劃分出兩個集合使得二者不在同一個集合裡面,然後我們直接遞迴即可。
Code
#include <bits/stdc++.h> using namespace std; #define Int register int #define MAXN //char buf[1<<21],*p1=buf,*p2=buf; //#define getchar() (p1==p2 && (p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) template <typename T> void read (T &x){char c = getchar ();x = 0;int f = 1;while (c < '0' || c > '9') f = (c == '-' ? -1 : 1),c = getchar ();while (c >= '0' && c <= '9') x = x * 10 + c - '0',c = getchar ();x *= f;} template <typename T,typename ... Args> void read (T &x,Args& ... args){read (x),read (args...);} template <typename T> void write (T x){if (x < 0) x = -x,putchar ('-');if (x > 9) write (x / 10);putchar (x % 10 + '0');} template <typename T> inline void chkmax (T &a,T b){a = max (a,b);} template <typename T> inline void chkmin (T &a,T b){a = min (a,b);} int n,x,y; #define poly vector<int> int getval (poly S){ cout << "? " << S.size() << " "; for (Int x : S) cout << x << " "; int v;cin >> v; return v; } int Solve (poly S){//找到S集合中y的位置 if (S.size() == 1) return S[0]; vector <int> T0,T1;int siz = S.size() >> 1; for (Int i = 0;i < siz;++ i) T0.push_back (S[i]); for (Int i = siz;i < S.size();++ i) T1.push_back (S[i]); int tmp = getval (T0); if ((siz & 1) && tmp == y) return Solve (T0); else if (!(siz & 1) && tmp == (x ^ y)) return Solve (T0); else return Solve (T1); } signed main(){ read (n,x,y);int det = 0; for (Int i = 0;(1 << i) <= n;++ i){ vector <int> S; for (Int k = 1;k <= n;++ k) if (!(k >> i & 1)) S.push_back (k); int tmp = getval (S); if ((S.size() & 1) && tmp == y) det |= (1 << i); else if (!(S.size() & 1) && tmp == (x ^ y)) det |= (1 << i); } for (Int i = 0;(1 << i) <= n;++ i) if (det >> i & 1){ vector <int> S; for (Int k = 1;k <= n;++ k) if (!(k >> i & 1)) S.push_back (k); int pos = Solve (S),ano = pos ^ det;if (pos > ano) swap (pos,ano); cout << "! " << pos << " " << ano << endl; return 0; } return 0; }