CF1621C - Hidden Permutations(搜索技术+交互题+数学规律/省选级)

1621C - Hidden Permutations(源地址自⇔CF

tag

⇔搜索技术、⇔交互题、⇔数学规律、⇔省选级(*1700)。

交互题解释

你需要与系统进行交互,通过有限次的自定义询问系统得到数据,并根据得到的数据得出唯一正确答案。

具体的操作过程是:使用 cout 进行询问,使用 cin 进行数据读入。需要注意的是,在每一次询问之后都需要将缓存区清空,可以使用: endlfflush(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 成文


posted @ 2022-01-04 20:39  hh2048  阅读(100)  评论(0编辑  收藏  举报