还是自己水平不够,想了两天没想出来……(然后我就被其他人吊打了)

这种题目看了题解就秒会,自己想就想不出来……

下面是我的心路历程(我就在想出来又叉掉的不断循环中度过……)

开始把题目看成了查询限制 \(2N\) 长度,然后怎么也不会做,看看题,发现是 \(4N\) (然而还是不会做)

首先一个很显然的想法,就是先两步找出第一个,然后后面的每个都用一步。最后一位可能要多耗费一个。此时总步数正好是 \(N + 2\)。

然后重点就在中间的了。

我们记剩下来的字符为 \(A, B, C\),当前处理好的字符串为 \(S\)。

首先很容易有一个想法:在一个串后面加一堆同一个字符,然后看增加了多少,这样有概率一下子增加多个。

如果把所有连续的长度求出来,那么每次枚举只有两种情况,貌似很优秀。

于是构造 \(\{ S + A + \dots, S + B + \dots\}\),发现没填满,应该不对,于是改成 \(\{ S + A + A + \dots, S + A + B +\dots, S + B + A + \dots, S + B + B + \dots \}\) 。

然后发现对于下面是 \(A\) 和 \(B\) 的都很好求,只要分类讨论增加了几个。

但是一旦有 \(C\) 就会有额外枚举量,所以这种想法放弃了。

接着考虑如果不求最长连续的,对三种情况暴力算的也许可以。比如说可以改成不断的求子问题的模型。

仔细分析发现这样做本质和每次只增加 \(O(1)\) 个字符是相同的。

所以考虑每次增加那么多。

接下来我类似地考虑了这个加同一个字符。

也就是询问 \(\{ S + A + A + A, S + A + B + B, S + B + A + A, S + B + B + B \}\)

显然也可以通过分类讨论加了多少个的情况。

对于没加的;显然是 \(C\),对于加了 \(1\) 的,枚举第一位就可以知道第 \(2\) 位;对于加了 \(3\) 的,显然可以查询两次得到。对于这几种情况,得到每一个的耗费都是 \(1\)。

然而这个做法还是挂在加了 \(2\) 的,冷静分析,发现直接确定第三位还是更优的,但是马上发现你要用两步确定 \(8\) 种情况,然后GG。

所以发现我的做法对于只增加了两个的都凑不出来(总会多一步)。

凑了那么多,发现最后还是要找一个对于所有位数,情况平均少一点的。但是有一个 \(3\) 就显得难做了。


直到我看了题解:

我的做法太贪了,一次确定多位不太行,没有去想一次只确定一位……(这个故事告诉我们,做题尽量由浅入深,从简单的开始考虑)

和分类讨论加了多少个的思想类似,这个十分的暴力……

直接把下一个是 \(A\) 就 \(+2\), 是 \(B\) 就 \(+1\), 是 \(C\) 就 \(+0\),显然这个很好构造 \(\{ S + A + A, S + A + B, S + A + C, S + B\}\)

显然满足。

然后注意对剩下的只有一个的特判,正好补上最后的多的一个。

然后我把 \(<\) 写成 \(\leq\),WA了一发……

#include "combo.h"

const char sx[] = {'A', 'B', 'X', 'Y'};
std::string S, li[3];
std::string d(int at) {
return at == 3 ? S : li[at];
}
template<typename ... T>
std::string d(int at, T ... args) {
return (at == 3 ? S : li[at]) + d(args...);
}
std::string guess_sequence(int N) {
char fir = press("AB") >= 1 ? (press("A") ? 'A' : 'B') : (press("X") ? 'X' : 'Y');
S += fir; int bx = 0;
for (int i = 0; i < 4; ++i)
if (sx[i] != fir) li[bx++] = std::string(1, sx[i]);
for (bx = 1; bx < N; ) {
std::string qry;
if (bx + 1 == N) {
S += press(d(3, 0)) == N ? li[0] : (press(d(3, 1)) == N ? li[1] : li[2]);
break;
}
int res = press(d(3, 0, 0, 3, 0, 1, 3, 0, 2, 3, 1)) - bx;
if (!res) S += li[2];
else if (res == 1) S += li[1];
else if (res == 2) S += li[0];
++bx;
}
return S;
}

【IOI2018】组合动作的更多相关文章

  1. [IOI2018]组合动作

    IOI2018 组合动作 UOJ 首先显然可以两次试出首字母 考虑增量构造 假设首字母为A,且已经试出前i个字母得到的串s 我们考虑press这样一个串s+BB+s+BX+s+BY+s+XA 首先这个 ...

  2. [IOI2018]组合动作——构造

    题目连接: [IOI2018]combo 题目大意:有一个未知的长度为n的字符串$T$,只包含$A,B,X,Y$四个字符且首字母只出现一次,每一次你可以询问一个长度不超过$4n$的字符串$S$,交互库 ...

  3. LOJ.2863.[IOI2018]组合动作(交互)

    题目链接 通过两次可以先确定首字母.然后还剩下\(n-1\)位,之后每一位只有三种可能. 最简单的方法是每次确定一位,通过两次询问显然可以确定.但是只能一次询问. 首字母只会出现一次,即我们可以将串分 ...

  4. 【刷题】LOJ 2863 「IOI2018」组合动作

    题目描述 你在玩一个动作游戏.游戏控制器有 \(4\) 个按键,A.B.X 和 Y.在游戏中,你用组合动作来赚金币.你可以依次按这些按键来完成一个组合动作. 这个游戏有一个隐藏的按键序列,可以表示为由 ...

  5. Cocos2d-x手机游戏开发中-组合动作

    动作往往不是单一,而是复杂的组合.我们可以按照一定的次序将上述基本动作组合起来,形成连贯的一套组合动作.组合动作包括以下几类:顺序.并列.有限次数重复.无限次数重复.反动作和动画.动画我们会在下一节介 ...

  6. UOJ#405. 【IOI2018】组合动作

    原文链接https://www.cnblogs.com/zhouzhendong/p/IOI2018Day1T1.html 题解 首先二分一下,花费2次操作求出第一位的字符. 假设第一个字符是 Y,答 ...

  7. 【IOI 2018】Combo 组合动作(模拟,小技巧)

    题目链接 IOI的签到题感觉比NOI的签到题要简单啊,至少NOI同步赛我没有签到成功…… 其实这个题还是挺妙妙的,如果能够从题目出发,利用好限制,应该是可以想到的做法的. 接下来开始讲解具体的做法: ...

  8. [loj2863]组合动作

    先用两次猜出第一个字符,后面就不会出现这个字符了 (我们假设这个字符是c0,其余三种字符分别是c1.c2和c3) ,然后考虑已知s的前i个字符(不妨就s),来推出后面的字符 询问:s+c1和s+c2, ...

  9. 【WC2019笔记】IOI2018 / ACM题目选讲

    哇!济南的 rqy 大佬讲课!就是 $luogu$ 上有名的那位! 上面这句话写错了,请大家无视 XylophoneIOI2018 练习赛 T2题意:交互提有一个 $0\sim n-1$ 的排列,保证 ...

随机推荐

  1. C++实用模板 | 党办大活动计分

    #include <iostream> #include <cmath> #include <cstring> #include <string> #i ...

  2. Git_基础命令

    gitinit//初始化一个Git仓库" role="presentation">gitinit//初始化一个Git仓库gitinit//初始化一个Git仓库 gi ...

  3. mybatis插入出现org.apache.ibatis.executor.ExecutorException: No setter found for the keyProperty 'xxx'异常的原因

    确定有setter方法,问题其实是xml文件中,insert的主键的列名写错了,如下,一开始写成ComId <insert id="insertCom" parameterT ...

  4. sql--ALTER

    ALTER TABLE 语句 ALTER TABLE 语句用于在已有的表中添加.修改或删除列. SQL ALTER TABLE 语法 如需在表中添加列,请使用下列语法: ALTER TABLE tab ...

  5. 提升scrapy的爬取效率

    增加并发: 默认scrapy开启的并发线程为32个,可以适当进行增加.在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100. 降低日志级别 ...

  6. unicode 和utf-8,GBK编码

    说到编码,得先从ASCII编码讲起.ASCII编码是由美国人发明,美国的字符不超过255个,所以ASCII编码使用了8bit 即一个字节来存储字符.由于汉字的数量远超255个,所以中国自己发明了一个G ...

  7. Python两个内置函数locals 和globals

    这两个函数主要提供,基于字典的访问局部和全局变量的方式.在理解这两个函数时,首先来理解一下python中的名字空间概念.Python使用叫做名字空间的东西来记录变量的轨迹.名字空间只是一个字典,它的键 ...

  8. python: 基本数据类型 与 内置函数 知识整理

    列表 list.append(val) #末尾追加,直接改变无返回 list.inert(2,val) #插入到指定位置 list.extend(mylist1) #list会被改变 list2=li ...

  9. python tkinter 基本使用

    这里只放表格和一个控件基本属性 grid(**options) 属性-- 下方表格详细列举了各个选项的具体含义和用法: 选项 含义column 1. 指定组件插入的列(0 表示第 1 列)2. 默认值 ...

  10. Vivado添加sublime text编辑器

    我们当用vivado会发现文本编辑器有点鸡肋,没有自动的缩进的功能,所以我想用sublime来进行文本的编辑,下面就是绑定的一些方法(但是呢其实吧,虽然可以绑定却不能实时的报错,,,我感觉我还是老老实 ...