题目传送门


分析

先尝试锁定一个字母,显然询问 \(CH,CO,CC\) 会比直接询问 \(C\) 更优,虽然牺牲了最后一个位置是否为 \(C\) 的查询。

同理,询问 \(HH,OH,CH\) 会比直接询问 \(H\) 更优,虽然牺牲了第一个位置是否为 \(H\) 的查询。

可以发现这样询问非首尾位置未填的一定是 \(O\),\(C,H\) 一定会被询问出来。

然后首字母只可能填 \(O,H\),尾字母只可能填 \(C,O\),然后再三次判断就可以知道整个串(如果三次判断都不知道,那只能是最后一种情况)

那么操作代价就是 \(\frac{5}{4}+\frac{4-1}{n^2}\),可以发现在 \(n>4\) 时都不超过 \(\frac{7}{5}\),\(n=5\) 时最小,为 \(1.37\)

那么只剩下 \(n=4\) 的情况,显然直接这样问肯定会代价过高。

可以发现只要确定其中两个位置,就可以花不超过 \(\frac{9-1}{16}\) 的代价确定其它位置,

还是尝试锁定 \(C\) 字母,如果锁定得了那么只需要花 \(\frac{3}{4}\) 的代价,

同时其它位置就可以花不超过 \(\frac{6-1}{16}\) 的代价,合起来就是 \(\frac{17}{16}\)

如果 \(C\) 字母不能锁定,再询问 \(OH\),同理,只需要花 \(\frac{4}{4}+\frac{6-1}{16}=\frac{21}{16}\) 的代价。

再询问 \(HH\),如果 \(H\) 被锁定,其实第一二位一定是 \(H\),如果不是那么它在之前一定会被询问出来。

如果第三四位没有被询问出来,那么第三位一定是 \(O\),否则第三位一定被询问出来,

同理只需要确定尾位,需要 \(\frac{5}{4}+\frac{1}{16}=\frac{21}{16}\)。

最后一种情况,中间两位一定是 \(O\),最后询问 \(OOO\),通过 \(\frac{5}{4}+\frac{1}{9}=\frac{49}{36}\) 就可以确定所有位置啦


代码

#include <iostream>
using namespace std;
const char ch[3]={'H','O','C'};
int k,x,Test,n,AC; char S[51];
void doit(char ch,char Ch){
cout<<"? "<<ch<<Ch<<endl;
cin>>k;
for (int i=0;i<k;++i)
cin>>x,S[x]=ch,S[x+1]=Ch;
}
void answ(int t){
bool flag=1;
if (S[1]=='\0'&&S[n]=='\0'){
for (int o=2;o>=t&&flag;--o)
for (int j=0;j<2&&flag;++j)
if (!t||o!=1||j!=1){
S[1]=ch[j],S[n]=ch[o],cout<<"? ";
for (int i=1;i<=n;++i) cout<<S[i]; cout<<endl;
cin>>k;
if (k) cin>>x,flag=0;
}
if (flag) S[1]=S[n]='O',flag=0;
}
for (int i=1;i<n&&flag;++i)
if (S[i]=='\0'&&S[i+1]=='\0'){
for (int o=0;o<3&&flag;++o)
if (!t||o<2||i==n-1)
for (int j=0;j<2&&flag;++j){
S[i]=ch[j],S[i+1]=ch[o],cout<<"? ";
for (int i=1;i<=n;++i) cout<<S[i]; cout<<endl;
cin>>k;
if (k) cin>>x,flag=0;
}
flag=0; break;
}
if (flag){
for (int i=1;i<=n;++i)
if (S[i]=='\0'){
for (int o=0;o<3&&flag;++o) if (!t||o<2||i==n){
S[i]=ch[o],cout<<"? ";
for (int i=1;i<=n;++i) cout<<S[i]; cout<<endl;
cin>>k;
if (k) cin>>x,flag=0;
}
}
}
cout<<"! ";
for (int i=1;i<=n;++i) cout<<S[i];
cout<<endl;
}
int main(){
ios::sync_with_stdio(0);
for (cin>>Test;Test;--Test){
cin>>n;
if (n>4){
for (int i=0;i<3;++i) doit('C',ch[i]);
doit('H','H'),doit('O','H');
for (int i=2;i<n;++i) if (S[i]=='\0') S[i]='O';
answ(1);
}else{
for (int i=0;i<3;++i) doit('C',ch[i]);
if (S[2]!='\0'||S[3]!='\0') answ(0);
else{
doit('O','H');
if (S[2]!='\0'||S[3]!='\0') answ(0);
else{
doit('H','H');
if (S[2]!='\0'){
if (S[4]=='\0'){
if (S[3]=='\0') S[3]='O';
cout<<"? ";
for (int i=1;i<4;++i) cout<<S[i];
cout<<'C'<<endl;
cin>>k;
if (k) cin>>x,S[4]='C';
else S[4]='O';
}
cout<<"! ";
for (int i=1;i<=4;++i) cout<<S[i];
cout<<endl;
}else{
S[2]=S[3]='O';
cout<<"? OOO"<<endl;
cin>>k;
if (k==2) cin>>x,cin>>x,S[1]=S[4]='O';
else if (k==1){
cin>>x,S[x]=S[x+2]='O';
if (S[1]=='\0') S[1]='H';
else S[4]='C';
}else S[1]='H',S[4]='C';
cout<<"! ";
for (int i=1;i<=4;++i) cout<<S[i];
cout<<endl;
}
}
}
}
for (int i=1;i<=n;++i) S[i]='\0';
cin>>AC;
}
return 0;
}

#交互,分类讨论#CF1292E Rin and The Unknown Flower的更多相关文章

  1. Codeforces 460D Little Victor and Set --分类讨论+构造

    题意:从区间[L,R]中选取不多于k个数,使这些数异或和尽量小,输出最小异或和以及选取的那些数. 解法:分类讨论. 设选取k个数. 1. k=4的时候如果区间长度>=4且L是偶数,那么可以构造四 ...

  2. BZOJ-1067 降雨量 线段树+分类讨论

    这道B题,刚的不行,各种碎点及其容易忽略,受不鸟了直接 1067: [SCOI2007]降雨量 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 2859 ...

  3. UVaLive 6862 Triples (数学+分类讨论)

    题意:给定一个n和m,问你x^j + y^j = z^j 的数量有多少个,其中0 <= x <= y <= z <= m, j = 2, 3, 4, ... n. 析:是一个数 ...

  4. 枚举(分类讨论):BZOJ 1177: [Apio2009]Oil

    1177: [Apio2009]Oil Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1477  Solved: 589[Submit] Descri ...

  5. Educational Codeforces Round 63 (Rated for Div. 2) D. Beautiful Array 分类讨论连续递推dp

    题意:给出一个 数列 和一个x 可以对数列一个连续的部分 每个数乘以x  问该序列可以达到的最大连续序列和是多少 思路: 不是所有区间题目都是线段树!!!!!! 这题其实是一个很简单的dp 使用的是分 ...

  6. 【cf789B】Masha and geometric depression(分类讨论/暴力)

    B. Masha and geometric depression 题意 在黑板上写数列,首项是b,公比是q,超过l时就停止不写.给定m个数,遇到后跳过不写.问一共写多少个数,如果无穷个输出inf. ...

  7. P2331 [SCOI2005]最大子矩阵 (动规:分类讨论状态)

    题目链接:传送门 题目: 题目描述 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. 输入输出格式 输入格式: 第一行为n,m,k( ...

  8. UVa 11722 Joining with Friend (几何概率 + 分类讨论)

    题意:某两个人 A,B 要在一个地点见面,然后 A 到地点的时间区间是 [t1, t2],B 到地点的时间区间是 [s1, s2],他们出现的在这两个区间的每个时刻概率是相同的,并且他们约定一个到了地 ...

  9. Bzoj4558:分类讨论 计算几何 组合数学

    国际惯例的题面: 这题让我爆肝啦......这种计数显然容斥,正好不含任何坏点的我们不会算,但是我们能算至少含零个坏点的,至少含一个坏点的,至少含两个坏点的......所以最终的答案就是(至少含零个坏 ...

  10. HDU 5203 Rikka with wood sticks 分类讨论

    题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5203 bc(chinese):http://bestcoder.hdu.edu.cn/con ...

随机推荐

  1. python模块imghdr-----推测图像类型

    官方文档 https://docs.python.org/zh-cn/3/library/imghdr.html#module-imghdr 用处 模块推测文件或字节流中的图像的类型 imghdr.w ...

  2. 【LeetCode哈希表#3】快乐数(set)

    快乐数 力扣题目链接(opens new window) 编写一个算法来判断一个数 n 是不是快乐数. 「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程 ...

  3. 【Azure 媒体服务】Azure Media Service Explorer 5.4.3.0 不能连接Media Service, 错误消息提示 BadRequest 和 Forbidden

    问题描述 Azure Media Service Explorer 5.4.3.0 不能连接Media Service, 错误消息提示 BadRequest 和 Forbidden. 截图如下: Ba ...

  4. Nebula Graph 源码解读系列 | Vol.00 序言

    本文首发于 Nebula Graph Community 公众号 Nebula Graph 是由杭州欧若数网科技有限公司(官网:https://www.vesoft.com/cn/)开源的一款分布式图 ...

  5. C++ STL 容器-Deque

    C++ STL 容器-Deque std::deque(双端队列)是C++标准模板库(STL)中的一个容器,它支持在序列的两端快速插入和删除元素.与std::vector和std::list等其他序列 ...

  6. MySQL联接表总结笔记

    SQL最强的的工呢过之一就是能够在护具检索查询的执行中联结表,联结表利用SQL的select能执行的最重要的操作,很好的理解联结及其语法学习SQL的一个重要的组成部分. 在能够有效的使用联结前,必须了 ...

  7. Gavvmal

    Gavvmal springboot 官方文档说明了两种方式,一种使用插件,直接生成docker镜像,但是这需要本地安装docker环境,但是无论用windows还是mac,本地安装docker都感觉 ...

  8. 解密prompt系列26. 人类思考vs模型思考:抽象和发散思维

    在Chain of Thought出来后,出现过许多的优化方案例如Tree of thought, Graph of Thought, Algorithm of Thought等等,不过这些优化的出发 ...

  9. Chrome Audio Capture - 录音插件 功能很简单,就是点击录音 文本转语音用

    Chrome Audio Capture - 录音插件 功能很简单,就是点击录音 文本转语音用

  10. 基于python的环境噪声监测报警系统实例解析

    一 系统简介 1.简介 该系统可以实时显示噪声量大小,并进行一段时间的噪声统计. 2.特性 实现噪声值的统计 实现了噪声显示 完整的主题和样式控制 多线程的运行模式 二 源码解析 1.串口db值获取: ...