Guess The String (CF2 D) (交互题+二分+26小写字母)
思路:
- 很多交互题, 大多要用二分, 这道题也不例外, 因为满足递增的条件
- 但是这个的操作复杂度是 nlogn的, 6000,一定不行的, 不要看到 nlogn 就认为是一定行的(中途想到了,但是还是就放掉了,md)
- 于是发现都是小写字母 一定要用26这个小写字母特性条件条件 这个东西来优化一下就行了!!!
#include <bits/stdc++.h> using namespace std; #define ri int #define M 2005 int n,m; int T; int arr[M][300]; char s[M]; int pos[M]; int qu[M]; int cur; int ck(int l,int r) { int ans=0; l=qu[l]; for(ri j='a';j<='z';j++) { int tmp=arr[r-1][j]-arr[l-1][j]; if(tmp) ans++; } cout<<"? "<<"2 "<<l<<" "<<r<<"\n"; fflush(stdout); int a; cin>>a; if(a==ans) return 1; else return 0; } int main(){ // ios::sync_with_stdio(false); // cin.tie(0);cout.tie(0); cin>>n; int cur=0; // 26 的约束条件 for(ri i=1;i<=n;i++) { cout<<"? "<<2<<" "<<1<<" "<<i<<"\n"; fflush(stdout); int a; cin>>a;fflush(stdout); if(a>cur) { cout<<"? "<<"1 "<<i<<"\n";fflush(stdout); cin>>s[i-1]; cur++; } else { cur=0; for(ri j='a';j<='z';j++) { if(pos[j]) qu[++cur]=pos[j]; } sort(qu+1,qu+1+cur); //for(ri i=1;i<=cur;i++) cout<<qu[i]<<" "; int l=1,r=cur; int ans=0; while(l<=r) { int mid=(l+r)>>1; if(ck(mid,i)) { ans=mid; l=mid+1; } else r=mid-1; } s[i-1]=s[qu[ans]-1]; } for(ri j='a';j<='z';j++) { arr[i][j]=arr[i-1][j]; } pos[s[i-1]]=i; arr[i][s[i-1]]++; } cout<<"! "<<s;fflush(stdout); return 0; }