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 }

 

posted @ 2019-02-09 17:52  sjkmost  阅读(154)  评论(0编辑  收藏  举报