cf1705 F. Mark and the Online Exam
作者:互联网
题意:
交互题。
猜 n 道判断题的答案。每次可询问一个长为 n 的T/F串,回答答对的题数
\(n\le 1000,\) 询问次数限制 \(675\)
思路:
先猜复杂度:\(\frac 23 n\) 左右
以下除法都是下取整。记 \(m=n/3\),
-
询问一个全 T 串,回答记为 \(q1\)
-
询问 \(n/3\) 次,第 \(i\) 次问一个除了第 \(i,i+m\) 两位为 F,其他位均为 T 的串。回答记为 \(q2_i\),那么有这几种情况:
- \(q1=q2_i+2\),说明正解为 \(s_{i}=s_{i+m}=T\)
- \(q1=q2_i-2\),说明正解为 \(s_{i}=s_{i+m}=F\)
- \(q1=q2_i\),说明正解是 TF/FT,但没法确定
-
询问一个前 \(1/3\) 为 F,其他为 T 的串(记为str),回答记为 \(q3\)
-
对第2步没法确定的位置 \(i(i\le m)\) 询问最多 \(n/3\) 次,第 \(i\) 次问一个第 \(i\) 位为 T、第 \(i+m\) 位为 F、第 \(i+2m\) 位为 F,其他位与 str 相同的串。回答记为 \(ans4_i\),那么有这几种情况:
- \(q3=q4_i+3\),说明正解为 \(s_i=F,s_{i+m}=T,s_{i+2m}=T\)
- \(q3=q4_i+1\),说明正解为 F,T,F
- \(q3=q4_i-1\),说明正解为 T,F,T
- \(q3=q4_i-3\),说明正解为 T,F,F
- 把剩下未确定的都单独问一下。4,5 两步加起来也是 \(n/3\) 级别
const signed N = 5 + 1000;
int n, m, q1, q2, q3, q4, q5;
void sol() {
cin >> n; m = n / 3;
string s(n,0), str, tmp; //答案串及用于询问的串
//q1
str = string(n,'T'); cout << str << endl; cin >> q1;
//q2
for(int i = 0; i < m; i++) {
tmp = str; tmp[i] = tmp[i+m] = 'F';
cout << tmp << endl; cin >> q2;
if(q1 == q2 + 2) s[i] = s[i+m] = 'T';
if(q1 == q2 - 2) s[i] = s[i+m] = 'F';
}
//q3
str = string(m,'F')+string(n-m,'T'); cout << str << endl; cin >> q3;
//q4
for(int i = 0; i < m; i++) if(!s[i]) {
tmp = str; tmp[i] = 'T'; tmp[i+m] = tmp[i+2*m] = 'F';
cout << tmp << endl; cin >> q4;
if(q3 == q4 + 3) s[i] = 'F', s[i+m] = 'T', s[i+2*m] = 'T';
if(q3 == q4 + 1) s[i] = 'F', s[i+m] = 'T', s[i+2*m] = 'F';
if(q3 == q4 - 1) s[i] = 'T', s[i+m] = 'F', s[i+2*m] = 'T';
if(q3 == q4 - 3) s[i] = 'T', s[i+m] = 'F', s[i+2*m] = 'F';
}
//q5
for(int i = 0; i < n; i++) if(!s[i]) {
tmp = string(n,'T'); tmp[i] = 'F';
cout << tmp << endl; cin >> q5;
s[i] = q1 > q5 ? 'T' : 'F';
}
cout << s << endl;
}
标签:q1,tmp,q3,q2,q4,正解,Online,cf1705,Exam 来源: https://www.cnblogs.com/wushansinger/p/16486841.html