IOI D1 T2 message

看了题后试图口胡,记录下做法。

题意

有删改,进行了简化。

A 要发给 B \(1024\) bit 的信息,每次发 \(31\) bit,总共发 \(S\) 轮。

但是,有中间人 C 可以看到信息并篡改,不过,他只能修改固定的 \(15\) 个 bit。

A 知道 C 控制了哪些 bit,并能在发送信息后知道 B 收到的信息;但是 B 只知道存在 \(15\) 个 bit 不可信,不知道确切的位置。

你的得分是(假设满分为 \(1\),Subtask 1 的 \(10\%\) 是容易的)

\[\begin{cases} 1 &S\le 66\\ 0.95^{S-66}\times0.9+0.1 &66\lt S\le 100\\ 0.1 &S>100 \end{cases} \]

思路

1

首先注意到如果一轮中 A 全发 1 / 0,可以保证传递 1 bit 的信息,因此可以用 \(31\) 轮传递每个位是否可信。剩下每轮可以传递 16 bit 的信息,总共 \(95\) 轮。

你可以拿到 \(30.33\%\) 的好成绩,rk195。

2

若 B 已知一定数量的“安全位”,一轮仍传递 \(1\) bit 的信息是浪费的,据此可以优化。

以及,另一种思路是传递“安全位”的位置。

优化一下 \(70\sim 90\) 轮可能都能做出来,不展开讲了。

3

我目前最优的确定正确的想法。

考虑前 \(16\) 位一定有一个“安全位”,我们可以用 \(4\) 轮传递它的位置。

剩下的,考虑用已知的一个“安全位”传递“安全位”的位置信息,其他安全位同时传递那 \(1024\) bit 的信息。

剩下安全位的位置种类是 \(\dbinom{30}{15}=155117520<2^{28}\),因此可以用 \(28\) bit 传递。

总共还要传 \(1024+28=1052\) bit,需要 \(\left\lceil\dfrac{1052}{16}\right\rceil=66\) 轮。

加起来 \(70\) 轮,\(83.31\%\),rk12。

4

口胡一下不知道对不对的正解。

发现 \(66\) 轮不满,最后空 \(4\) 个 bit,我们尝试删掉最开始的 \(4\) 轮,将 \(4\) bit 的信息放在这个空里,正好 \(66\) 轮,没有浪费。

但接受方不知道最初的“安全位”是啥了。

考虑枚举,最后检验正确性。

尽管交互库在猜到 A 与 B 的协议时可以构造多解,但由于 A 和 B 实际可以将发出或接受的信息异或一个固定值(并且 \(4\) 个“检验位”可以打乱在 \(1024\) bit 的信息中),交互库其实难以自适应,行为应该随机(不一定是简单的对每个位随机更改,但肯定难以对着你的解法卡)。

5

可以尝试写一个压缩算法,不过 \(1024\) bit 有点小,并且如果数据是随机生成的,信息熵会很高,压缩算法可能反而增加信息长度。

6

正解。

首先 \((4)\) 没试过能不能过,但肯定不是出题人期望的做法。

\(a_0,a_1,a_2,\cdots,a_{15}\) 是“安全位”的位置,形式地,记 \(a_{16}=a_0+31\)

对于每个位置,计算这个位置到下一个位置的距离,即 \(d_{i}=d_{i+1}-d_{i}-1~(0\le d\le 15)\),显然 \(\sum d=16\)

对于位置 \(i\),设 \(s_j\) 是其第 \(j\) 轮的信息,我们令 \(s_k=0~(k\lt d_i),~s_{d_{i}}=1\),这样我们刚好用掉 \(31\) 个 bit。

接受方接受信息时,对于每个位,不论“安全”与否,都能解码出一个对应的 \(d\),指向它的下一个位置。

这构成一个内向基环树森林,注意到我们“安全位”的信息构成一个大小 \(16\) 的环,这将是图中最大的环。

现在,接受方已知哪些位可信,继续读取信息即可。

原题实际要求信息大小 \(\le 1024\),不过我们还剩一个位没用。不妨强制在信息后加入一个 \(1\),然后填充 \(0\) 直到长度为 \(1025\)。解码时显然可以还原。

posted @ 2024-09-03 21:13  weilycoder  阅读(13)  评论(0编辑  收藏  举报