分两种情况讨论:
k≤n,先猜至多 k 次 1,由于回答 <1 肯定是假的,所以可以把剩余系下是哪次错试出来,然后用至多 n 次搞定。
k>n,每个数都猜两次,如果两次结果不一样,再猜第三次确定哪个是真的,之后就可以当它一直说真话了(n 次内不会再说假话)
代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pli pair<LL, int> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head char s[10], t[10]; int main() { int n, k; scanf("%d %d", &n, &k); LL l = 1, r = (1LL<<n)-1, m = l+r >> 1; if(k <= n) { for (int i = 1; i <= k; i++) { printf("1\n"); fflush(stdout); scanf("%s", s); if(s[0] == '=') exit(0); else if(s[0] == '>') break; } int cnt = 0; while(l < r) { ++cnt; printf("%lld\n", m); fflush(stdout); scanf("%s", s); if(cnt%k == 0) { if(s[0] == '=') exit(0); else if(s[0] == '>') l = m+1; else r = m-1; } else { if(s[0] == '=') exit(0); else if(s[0] == '>') r = m-1; else l = m+1; } m = l+r >> 1; } printf("%lld\n", m); fflush(stdout); } else { bool f = true; while(l < r) { if(f) { printf("%lld\n", m); fflush(stdout); scanf("%s", s); printf("%lld\n", m); fflush(stdout); scanf("%s", t); if(s[0] != t[0]) { f = false; continue; } else if(s[0] == '=') exit(0); else if(s[0] == '>') r = m-1; else l = m+1; } else { printf("%lld\n", m); fflush(stdout); scanf("%s", s); if(s[0] == '=') exit(0); else if(s[0] == '>') r = m-1; else l = m+1; } m = l+r >> 1; } printf("%lld\n", m); fflush(stdout); } return 0; }