zoukankan      html  css  js  c++  java
  • [IOI2018]组合动作——构造

    题目连接:

    [IOI2018]combo

    题目大意:有一个未知的长度为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<cstring>
    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<n;i++)
    	{
    		int ans=press(now+s1+now+s2+s1+now+s2+s2+now+s2+s3)-(i-1);
    		ans==0?now+=s3:(ans==1?now+=s1:now+=s2);
    	}
    	press(now+s1)==n?now+=s1:(press(now+s2)==n?now+=s2:now+=s3);
    	return now;
    }
  • 相关阅读:
    event.srcElement就是指向触发事件的元素,他是什么就有什么的属性
    HTML title属性换行显示的方法
    O(∩_∩)O哈哈~
    练习题 英文正常语句倒序书写,标点位置不变
    累了就请休息一下。。。
    给自定义用户控件传递参数
    repeater做成gridview【更新删除编辑等】
    【公众号系列】12306购票送温暖
    【公众号系列】超详细SAP HANA JOB全解析
    【公众号系列】浅谈SAP项目管理的技能
  • 原文地址:https://www.cnblogs.com/Khada-Jhin/p/10323966.html
Copyright © 2011-2022 走看看