CF1621C - Hidden Permutations(搜索技术+交互题+数学规律/省选级)
1621C - Hidden Permutations(源地址自⇔CF)
tag
⇔搜索技术、⇔交互题、⇔数学规律、⇔省选级(*1700)。
交互题解释
你需要与系统进行交互,通过有限次的自定义询问系统得到数据,并根据得到的数据得出唯一正确答案。
具体的操作过程是:使用 cout
进行询问,使用 cin
进行数据读入。需要注意的是,在每一次询问之后都需要将缓存区清空,可以使用: endl
、 fflush(stdout)
或 cout.flush()
。
题意
有一个长度为 \(n\) 的未知序列 \(p[1 ... n]\) 、一个 \(1\) 到 \(n\) 的全排列序列 \(q[1 ... n]\) 。每一轮开始,都会进行一定的操作,规则如下:
- \(q[]\) 以 \(p[]\) 为映射进行一次变换。
- 你可以询问得到任何一个 \(q_i\) 的值。
你需要在 \(2*n\) 轮之内得出 \(p[]\) 。
思路
显然的结论:
- 第一轮的 \(q[]\) 就是 \(1\) 到 \(n\) 的全排列。
- 第二轮的 \(q[]\) 就是 \(p[]\) ,所以第二次询问一定能得出一个正确的元素。
- 对于此后的每一轮而言,上一轮的 \(q_{old}[]\) 满足 \(p[q_{old}[i]] = p[i]\) 。
我们先考虑一般情况——如果所有的 \(p[i] \neq i\) ,则 \(n - 1\) 次询问同一个 \(i\) 一定能得到一个完整的 \(p[]\) ,第 \(n+1\) 次询问与第 \(1\) 次相同,开始新的一轮循环。
如:
p = [3, 1, 2, 4]
q = [1, 2, 3, 4] -> [3, 1, 4, 2] -> [4, 3, 2, 1] -> [2, 4, 1, 3] -> [1, 2, 3, 4]
故一个映射是 p[1] = 3, p[3] = 4, p[4] = 2, p[2] = 1。
然后我们考虑特殊情况——如果有 \(p[i] = i\) 。例如样例二,我们关注 \(i=1\) ,发现第 \(2\) 次与第 \(1\) 次相同,开始一轮新的循环。
p = [1, 3, 4, 2]
q = [1, 2, 3, 4] -> [1, 3, 4, 2] -> [1, 4, 2, 3] -> [1, 2, 3, 4]
继续考虑特殊情况——如果有 \(p[i] = j,p[j] = i\) 。如下方样例,我们关注 \(i = 3\) ,发现第 \(3\) 次与第 \(1\) 次相同,开始一轮新的循环。
p = [1, 2, 4, 3]
q = [1, 2, 3, 4] -> [1, 3, 4, 3] -> [1, 2, 3, 4]
综合上述可以猜测,对于 \(p[i]\) 未知的 \(i\) ,连续询问,直到得到一个循环,记录,并继续寻找下一个 \(p[i]\) 未知的 \(i\) 。
可以简单的证明可行性:最好的情况是一般情况, \(n + 1\) 次可以得到答案;最差的情况是 \(p\) 恰好是 \(1\) 到 \(n\) 的全排列,对于每一个 \(i\) ,需要 \(2\) 次询问得到循环,一共 \(2*n\) 次可以得到答案,均满足题目的限制。
AC代码(伪代码)
void clear() {
ans = 0; Ans = true;
num = 1; add = 0;
ms(flag, 0);
}
LL ask(LL i) {
add ++;
LL j;
cout << "? " << i << endl;
cout.flush();
cin >> j;
return j;
}
void solve() {
VLL v;
cin >> n;
while(1) {
v.clear();
FOR(i, 1, n + 1) {
x = ask(num);//询问下一个元素
v.pb(x);
flag[x] ++;//标记已得到答案的i
if((i != 1 && x == v[0]) || add >= 2 * n) break;//循环结束,或者超出询问次数限制
}
FOR(i, 1, v.size() - 1) {//记录答案
a[v[i - 1]] = v[i];
}
FOR(i, 1, n) {
if(flag[i] == 0)//找到下一个未得到答案的p[i]
num = i;
}
}
cout << "! ";
FOR(i, 1, n)
cout << a[i] << " ";
cout << endl;cout.flush();
}
错误次数
文 / WIDA
2022.01.04 成文
首发于WIDA个人博客,仅供学习讨论
更新日记:
2022.01.04 成文