博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[IOI2018]组合动作——构造
阅读量:5905 次
发布时间:2019-06-19

本文共 1077 字,大约阅读时间需要 3 分钟。

题目连接:

题目大意:有一个未知的长度为n的字符串$T$,只包含$A,B,X,Y$四个字符且首字母只出现一次,每一次你可以询问一个长度不超过$4n$的字符串$S$,交互库会返回$S$的子串与$T$的前缀的最大公共长度,要求在不超过$n+2$次询问后获得$T$串。

首先首字母只出现一次,我们可以先搞清首字母是什么。

如果一个一个试需要三次,但如果我们二分询问就只需要两次。

具体来说第一次询问$AB$,如果返回$1$则询问$A$,否则询问$X$。

得到首字母之后我们可以想到一个$O(2n)$的做法:

剩下每一位只有三种可能性,我们每次在已知前缀后面加一个字母来试出下一个,每一位需要试两次。

但是可以发现我们并没有用到询问串长度不大于$4n$的条件。

我们假设首字母为$A$,当前已知$T$串的前缀为$s$,那么利用上述条件我们可以用一次询问就得出下一个字母是什么。

因为首字母只会出现一次,所以我们可以将四个长度不超过$n$的询问串连在一起询问,而询问时匹配的$S$的子串一定是四个拼接的询问串中的一个,而不会跨越两个串。

那么我们只需要每次查询$sBsXBsXXsXY$即可,如果返回值为$0$则是$Y$;返回值是$1$则是$B$;返回值是$2$则是$X$。

但要注意最后一位这样询问会超出询问长度限制且返回值无法判断,所以需要特判,这样第一位和最后一位消耗两次,其他位的确定只消耗一次,一共$n+2$次。

#include"combo.h"#include
using namespace std;string first;string now;string s1,s2,s3;int cnt;int n;std::string guess_sequence(int N){ n=N; first=press("AB")?(press("A")?"A":"B"):(press("X")?"X":"Y"); now=first; first=="A"?s1="B",s2="X",s3="Y":"1"; first=="B"?s1="A",s2="X",s3="Y":"1"; first=="X"?s1="B",s2="A",s3="Y":"1"; first=="Y"?s1="B",s2="X",s3="A":"1"; if(n==1) { return now; } for(int i=2;i

转载于:https://www.cnblogs.com/Khada-Jhin/p/10323966.html

你可能感兴趣的文章
Maven学习总结(十)——使用Maven编译项目gbk的不可映射问题
查看>>
2018-04-17 Linux学习
查看>>
读取json文件(基础篇)
查看>>
JavaScript学习总结(2)——JavaScript数据类型判断
查看>>
使用logrotate管理nginx日志文件
查看>>
iRedMail调整附件大小 & Postfix的bcc(自动转发/邮件备份/监控/归档) 在同一个服务器是有压力...
查看>>
MyEclipse+Tomcat+MAVEN+SVN项目完整环境搭建
查看>>
《Effective C++第三版》读书笔记——让自己习惯C++
查看>>
linux查看日志 (常用命令)
查看>>
解决首次安装android sdk platform-tools文件夹下adb命令无法运行
查看>>
我的友情链接
查看>>
dreamweaver如何限制用户只能提交一次表单要求
查看>>
如何防止博客,网站被挂马
查看>>
perl的魅力
查看>>
细谈jar项目文件编译---my note
查看>>
他卖2000W数据
查看>>
在Android 中使用KSOAP2调用WebService(二)
查看>>
设计模式原则篇(4):接口隔离原则---Interface Segregation Principle
查看>>
解决有些浏览器对加载相同的Action只加载一次的解决方法
查看>>
Solaris中查看硬件信息常用命令
查看>>