潜龙未见静水流,沉默深藏待时秋。一朝破空声势振,惊世骇俗展雄猷。
随笔 - 82, 文章 - 0, 评论 - 3, 阅读 - 2153

CF1292E Rin and The Unknown Flower 题解

目录

题目描述

这是一道交互题。

T 组数据,交互库有一个长为 n 的字符串 s ,字符集为 C,H,O

每次你可以给交互库传送一个字符串 t ,交互库会返回 ts 中出现的所有位置。

具体的,记 |t|=m ,则 a 被返回当且仅当 sa,a+m1=t ,并且这次交互的代价为 1m2

要求总代价 75 ,求字符串 s

数据范围

  • 1T500,4n50

时间限制 2s ,空间限制 256MB

分析

基本思路为,求出 CH 的所有出现位置,其余为 O

直接询问 C 代价过高,考虑询问 CC,CH,CO ,这样可以在 34 的代价内获得除 sn 外所有 C 的位置。

类似的,询问 CH,HH,OH 即可获得除 s1 外的所有 H 的位置,注意 CH 已经问过了。

于是除了 s1sn ,所有位置已经可以唯一确定。

如果 s1,sn 尚未确定,那么 s1{H,O},sn{C,O} 仅有 4 种情况。

逐一尝试可以做到在 54+3n2 的代价内求出 s

还可以继续优化,先求 s1 再求 sn 即可做到总代价 54+1(n1)2+1n2

n5 时,总代价不超过 1.3525 ,符合要求。

于是我们只需要单独处理 n=4 的情况。


然而这才是本题难点。

先询问 CC,CH,CO,HO

  • 如果有收获,那么至多还有两位没有确定,并且仅有 s4 可能为 C

    因此至多有 2×3=6 种可能情况,逐一询问代价为 44+516=1.0625

  • 如果没有收获,仅有 HHHC,HHHH,OHHC,OHHH,OOHH,OOHC,OOOC,OOOH,OOOO9 种可能情况。

    先询问 HHH,OOO ,这样候选集合大小不超过 3 ,逐一询问代价为 44+29+2161.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;
}

posted on   peiwenjun  阅读(4)  评论(0编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示