0%

The 2025 ICPC 德国 German Collegiate Programming Contest——J. Jumbled Packets(使用22作为分隔符,其他地方不能出现22这样子的分隔符)

题目大意

这是一道交互题,你的程序会对每个测试用例被运行两次

编码阶段(Encode):给你一个长度为 nn 的二进制串 ss(仅含 01),你需要输出一个长度同为 nn 的三进制串(可使用 012)。

解码阶段(Decode):你在编码阶段输出的三进制串会被做一次循环旋转(即取某个后缀拼上对应的前缀,也可能不旋转),然后作为输入给你。你需要根据这个被旋转过的三进制串,还原出编码阶段的原始二进制串。

换句话说,你需要设计一种编码方案,使得即使编码后的串被任意循环旋转,你仍然能唯一地解码出原始二进制串。编码串长度必须和原串相同,且只能使用三种字符。

数据范围1n1051 \le n \le 10^5

样例 1:编码阶段,原始串为 001,编码输出 002。解码阶段,收到的是 002 循环旋转后的 200,需要还原出 001

1
2
3
4
5
6
7
输入(编码阶段):
Encode
3
001

输出:
002
1
2
3
4
5
6
7
输入(解码阶段):
Decode
3
200

输出:
001

样例 2:编码阶段,原始串为 0100,编码输出 2100。解码阶段,收到的恰好没有旋转,仍为 2100,需要还原出 0100

1
2
3
4
5
6
7
输入(编码阶段):
Encode
4
0100

输出:
2100
1
2
3
4
5
6
7
输入(解码阶段):
Decode
4
2100

输出:
0100

思路讲解

使用二二作为分隔符。其他地方不允许出现二二为分隔符的这个情况。

长度大于8位的时候,使用二二作为分隔符,把这个字符串,把二进制字符串的前8位转化为6位,然后前面添上二二。然后转换的这6位三进制字符串要求第一位 不能为二,最后一位不能为二,然后其中不能有二二这样子的字符。然后这样子转好以后,然后就好了。这样子转好以后呢,在解码的时候,我们就能够看到这个22的地方,然后我们知道我们的22都是放在开头的,我们就知道这个字符串它到底被循环移动了几位

之所以不用二作为分隔符,就是不用一个二作为分隔符,是因为只用一个二的话,那么相当于你后面的就是二进制的字符串了,你后面就是一个二进制的字符串了,它造成了非常大量的信息的损失,所以我们就选用二二作为分隔符。当然你也可以用三个二,用四个二作为分隔符,但是那个可能会更加复杂。谢谢,但是意思反正是这个意思。

那么如果说长度小于8位的时候呢?长度小于8位的时候,我们是这样子做,就是直接暴力的进行双射就可以了。

包括长度大于8位,怎么把那6位给转回8位,我们也是用双设,就是直接我们下面放一个这个代码吧,就是非常暴力的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
const ll len2=8,len3=6;
vector<string> two_s;
// 生成该长度的二进制串
for (ll status=0;status<(1<<len2);++status) {
string sta;
ll op_status=status;
while (true) {
if (op_status==0) {
break;
}
sta.push_back('0'+(op_status&1));
op_status/=2;
}
sta.resize(len2,'0');
two_s.push_back(sta);
}
ll idx=0;
for (ll status=0;status<pow_three[len3];++status) {
string sta;
ll op_status=status;
while (true) {
if (op_status==0) {
break;
}
sta.push_back('0'+op_status%3);
op_status/=3;
}
sta.resize(len3,'0');
// 不允许开头为 2 ,这个是因为如果说开头为二的话,会造成一些问题。就是开头二如果连着前面那个二,然后就就,它会造成一个连接,能相当于又造出来一个二二,这个是会造成混乱的。
if (!(sta.find("22")==-1 && sta.front()!='2')) {
continue;
}
three_to_two[sta]=two_s[idx];
two_to_three[two_s[idx]]=sta;
++idx;
if (idx>=two_s.size()) {
break;
}
}

AC代码

AC
https://qoj.ac/submission/2031795
AC
https://codeforces.com/gym/106129/submission/362719223

心路历程(WA,TLE,MLE……)