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;

}
View Code

 

posted @ 2023-03-08 00:25  VxiaohuanV  阅读(15)  评论(0编辑  收藏  举报