UOJ 405(IOI2018 D1T1)
交互题
有一个长为$N$的由$A,B,X,Y$组成的字符串$S$,其中首字母不会重复出现。给定$N$,求$S$,可以询问一个字符串的最长的为$S$前缀的子串长度,询问次数不超过$N+2$即为满分,询问串长度不超过$4N$。
$$1\le N\le2000$$
考虑先$2$次问出首字母,则之后可以用首字母作“分隔符”,然后考虑每个字符依次询问。
对于第$2$到第$N-1$个字符,设当前答案串为$T$,三个不是首字母的字符分别为$p,q,r$,则如果询问$TpTqpTqqTqr$,则可以根据返回值的不同确定当前字符,最后用$2$次询问问出第$N$个字符即可。
1 const std::string C[4] = {"A", "B", "X", "Y"}; 2 3 std::string guess_sequence(int N) { 4 int first = press("AB") ? press("B") : press("Y") + 2; 5 std::string answer = C[first]; 6 int x, y, z, cur = 0; 7 FOR(j, 0, 4) { 8 if (j == first) { 9 continue; 10 } 11 ++ cur; 12 switch (cur) { 13 case 1: 14 x = j; 15 break; 16 case 2: 17 y = j; 18 break; 19 case 3: 20 z = j; 21 break; 22 } 23 } 24 FOR(i, 2, N) { 25 int result = press(answer + C[x] + answer + C[y] + C[x] + answer + C[y] + C[y] + answer + C[y] + C[z]); 26 if (result == i - 1) { 27 answer += C[z]; 28 } else if (result == i) { 29 answer += C[x]; 30 } else { 31 answer += C[y]; 32 } 33 } 34 if (N != 1) { 35 if (press(answer + C[x]) == N) { 36 answer += C[x]; 37 } else if (press(answer + C[y]) == N) { 38 answer += C[y]; 39 } else { 40 answer += C[z]; 41 } 42 } 43 return answer; 44 }