CF1292E Rin and The Unknown Flower 题解
题目描述
这是一道交互题。
\(T\) 组数据,交互库有一个长为 \(n\) 的字符串 \(s\) ,字符集为 C,H,O 。
每次你可以给交互库传送一个字符串 \(t\) ,交互库会返回 \(t\) 在 \(s\) 中出现的所有位置。
具体的,记 \(|t|=m\) ,则 \(a\) 被返回当且仅当 \(s_{a,a+m-1}=t\) ,并且这次交互的代价为 \(\frac1{m^2}\) 。
要求总代价 \(\le\frac 75\) ,求字符串 \(s\) 。
数据范围
- \(1\le T\le 500,4\le n\le 50\) 。
时间限制 \(\texttt{2s}\) ,空间限制 \(\texttt{256MB}\) 。
分析
基本思路为,求出 C 和 H 的所有出现位置,其余为 O 。
直接询问 C 代价过高,考虑询问 CC,CH,CO ,这样可以在 \(\frac 34\) 的代价内获得除 \(s_n\) 外所有 C 的位置。
类似的,询问 CH,HH,OH 即可获得除 \(s_1\) 外的所有 H 的位置,注意 CH 已经问过了。
于是除了 \(s_1\) 和 \(s_n\) ,所有位置已经可以唯一确定。
如果 \(s_1,s_n\) 尚未确定,那么 \(s_1\in\{\texttt H,\texttt O\},s_n\in\{\texttt C,\texttt O\}\) 仅有 \(4\) 种情况。
逐一尝试可以做到在 \(\frac 54+\frac 3{n^2}\) 的代价内求出 \(s\) 。
还可以继续优化,先求 \(s_1\) 再求 \(s_n\) 即可做到总代价 \(\frac54+\frac1{(n-1)^2}+\frac1{n^2}\) 。
当 \(n\ge 5\) 时,总代价不超过 \(1.3525\) ,符合要求。
于是我们只需要单独处理 \(n=4\) 的情况。
然而这才是本题难点。
先询问 CC,CH,CO,HO 。
-
如果有收获,那么至多还有两位没有确定,并且仅有 \(s_4\) 可能为
C。因此至多有 \(2\times 3=6\) 种可能情况,逐一询问代价为 \(\frac 44+\frac 5{16}=1.0625\) 。
-
如果没有收获,仅有
HHHC,HHHH,OHHC,OHHH,OOHH,OOHC,OOOC,OOOH,OOOO共 \(9\) 种可能情况。先询问
HHH,OOO,这样候选集合大小不超过 \(3\) ,逐一询问代价为 \(\frac 44+\frac 29+\frac 2{16}\approx 1.3472\) 。
综上我们用不超过 \(1.3525\) 的总代价解决了此题。
#include<bits/stdc++.h>
using namespace std;
string s;
char ch[3]={'C','H','O'};
inline int read()
{
int q=0;char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) q=10*q+ch-'0',ch=getchar();
return q;
}
vector<int> query(string s)
{
cout<<"? "<<s<<endl;
static vector<int> vec;
vec.resize(read());
for(auto &p:vec) p=read()-1;
return vec;
}
void work(string t)
{
for(auto p:query(t)) for(int i=0;i<t.size();i++) s[p+i]=t[i];
}
string check(string s1,string s2,string s3)
{
if(query(s1).size()) return s1;
if(query(s2).size()) return s2;
return s3;
}
string solve(int n)
{
s.resize(n);
for(int i=0;i<n;i++) s[i]='?';
if(n>=5)
{
work("CC"),work("CH"),work("CO"),work("HH"),work("OH");
for(int i=1;i<=n-2;i++) if(s[i]=='?') s[i]='O';
work('H'+s.substr(1,n-2));
if(s[0]=='?') s[0]='O';
work(s.substr(0,n-1)+'C');
if(s[n-1]=='?') s[n-1]='O';
return s;
}
work("CC"),work("CH"),work("CO"),work("HO");
if(count(s.begin(),s.end(),'?')<=2)
{
string t=" ";
vector<string> vec;
for(int a=0;a<=2;a++)
for(int b=0;b<=2;b++)
for(int c=0;c<=2;c++)
for(int d=0;d<=2;d++)
{
t[0]=ch[a],t[1]=ch[b],t[2]=ch[c],t[3]=ch[d];
int flg=1;
for(int i=0;i<4;i++) flg&=s[i]==t[i]||(s[i]=='?'&&(i==3||t[i]!='C'));
if(flg) vec.push_back(t);
}
for(auto t:vec) if(t==vec.back()||query(t).size()) return t;
}
if(query("HHH").size()) return check("HHHC","HHHH","OHHH");
if(query("OOO").size()) return check("OOOC","OOOH","OOOO");
return check("OHHC","OOHH","OOHC");
}
int main()
{
for(int t=read();t--;)
{
string s=solve(read());
cout<<"! "<<s<<endl,assert(read());
}
return 0;
}
本文来自博客园,作者:peiwenjun,转载请注明原文链接:https://www.cnblogs.com/peiwenjun/p/17446836.html
浙公网安备 33010602011771号