CF1292E Rin and The Unknown Flower 题解
目录
题目描述
这是一道交互题。
组数据,交互库有一个长为 的字符串 ,字符集为 C,H,O
。
每次你可以给交互库传送一个字符串 ,交互库会返回 在 中出现的所有位置。
具体的,记 ,则 被返回当且仅当 ,并且这次交互的代价为 。
要求总代价 ,求字符串 。
数据范围
- 。
时间限制 ,空间限制 。
分析
基本思路为,求出 C
和 H
的所有出现位置,其余为 O
。
直接询问 C
代价过高,考虑询问 CC,CH,CO
,这样可以在 的代价内获得除 外所有 C
的位置。
类似的,询问 CH,HH,OH
即可获得除 外的所有 H
的位置,注意 CH
已经问过了。
于是除了 和 ,所有位置已经可以唯一确定。
如果 尚未确定,那么 仅有 种情况。
逐一尝试可以做到在 的代价内求出 。
还可以继续优化,先求 再求 即可做到总代价 。
当 时,总代价不超过 ,符合要求。
于是我们只需要单独处理 的情况。
然而这才是本题难点。
先询问 CC,CH,CO,HO
。
-
如果有收获,那么至多还有两位没有确定,并且仅有 可能为
C
。因此至多有 种可能情况,逐一询问代价为 。
-
如果没有收获,仅有
HHHC,HHHH,OHHC,OHHH,OOHH,OOHC,OOOC,OOOH,OOOO
共 种可能情况。先询问
HHH,OOO
,这样候选集合大小不超过 ,逐一询问代价为 。
综上我们用不超过 的总代价解决了此题。
#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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?