题目大意
这是一道交互题,你的程序会对每个测试用例被运行两次。
编码阶段(Encode):给你一个长度为 n 的二进制串 s(仅含 0 和 1),你需要输出一个长度同为 n 的三进制串(可使用 0、1、2)。
解码阶段(Decode):你在编码阶段输出的三进制串会被做一次循环旋转(即取某个后缀拼上对应的前缀,也可能不旋转),然后作为输入给你。你需要根据这个被旋转过的三进制串,还原出编码阶段的原始二进制串。
换句话说,你需要设计一种编码方案,使得即使编码后的串被任意循环旋转,你仍然能唯一地解码出原始二进制串。编码串长度必须和原串相同,且只能使用三种字符。
数据范围:1≤n≤105。
样例 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'); 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
源代码
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
|
#include <bits/stdc++.h> #define all(vec) vec.begin(),vec.end() #define lson(o) (o<<1) #define rson(o) (o<<1|1) #define SZ(a) ((long long) a.size()) #define debug(var) cerr << #var <<" = ["<<var<<"]"<<"\n"; #define debug1d(a) \ cerr << #a << " = ["; \ for (int i = 0; i < (int)(a).size(); i++) \ cerr << (i ? ", " : "") << a[i]; \ cerr << "]\n"; #define debug2d(a) \ cerr << #a << " = [\n"; \ for (int i = 0; i < (int)(a).size(); i++) \ { \ cerr << " ["; \ for (int j = 0; j < (int)(a[i]).size(); j++) \ cerr << (j ? ", " : "") << a[i][j]; \ cerr << "]\n"; \ } \ cerr << "]\n"; #define debug3d(a) \ cerr << #a << " = [\n"; \ for (int i = 0; i < (int)(a).size(); i++) \ { \ cerr << " [\n"; \ for (int j = 0; j < (int)(a[i]).size(); j++) \ { \ cerr << " ["; \ for (int k = 0; k < (int)(a[i][j]).size(); k++) \ cerr << (k ? ", " : "") << a[i][j][k]; \ cerr << "]\n"; \ } \ cerr << " ]\n"; \ } \ cerr << "]\n"; #define cend cerr<<"\n-----------\n" #define fsp(x) fixed<<setprecision(x)
using namespace std;
using ll = long long; using ull = unsigned long long; using DB = double;
using CD = complex<double>;
static constexpr ll MAXN = (ll)1e6+10, INF = (1ll<<61)-1; static constexpr ll mod = 998244353; static constexpr double eps = 1e-8; const double pi = acos(-1.0);
ll lT,testcase;
bool is_unique(const string &s,const map<string,string> &mp){ for (int i=0;i<s.size();++i) { string ops=s; rotate(ops.begin(),ops.begin()+i+1,ops.end()); if (mp.contains(ops)) { return false; } } return true; } string find_str(const string &s,const map<string,string> &mp) { for (int i=0;i<s.size();++i) { string ops=s; rotate(ops.begin(),ops.begin()+i+1,ops.end()); auto it=mp.find(ops); if (it!=mp.end()) { return it->second; } } assert(true); return "Error"; } void Solve() { string op; cin>>op; ll N; cin>>N; map<string,string> three_to_two; map<string,string> two_to_three; vector<ll> pow_three(20); pow_three[0]=1; for (int i=1;i<=15;++i) { pow_three[i]=pow_three[i-1]*3; } if (N<=8) { do { for (ll len=1;len<=8;++len) { vector<string> two_s; for (ll status=0;status<(1<<len);++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(len,'0'); two_s.push_back(sta); } ll idx=0; for (ll status=0;status<pow_three[len];++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(len,'0'); if (is_unique(sta,three_to_two)) { three_to_two[sta]=two_s[idx]; two_to_three[two_s[idx]]=sta; ++idx; } if (idx>=two_s.size()) { break; } } } }while (false); }else { 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'); if (!(sta.find("22")==-1 && sta.front()!='2' && sta.back()!=2)) { continue; } three_to_two[sta]=two_s[idx]; two_to_three[two_s[idx]]=sta; ++idx; if (idx>=two_s.size()) { break; } } }
if (op=="Encode") { string s; cin >> s; if (N<=8) { cout<<two_to_three[s]<<"\n"; return; } string pre8(s.begin(),s.begin()+8); string thr6=two_to_three[pre8]; string code="22"+thr6+string(s.begin()+8,s.end()); cout<<code<<"\n"; }else { string s; cin >> s; if (N<=8) { cout<<find_str(s,three_to_two)<<"\n"; return; } ll pos22=s.find("22"); if (pos22==-1) { rotate(s.begin(),s.begin()+SZ(s)-1,s.end()); }else { rotate(s.begin(),s.begin()+pos22,s.end()); } string code=three_to_two[string(s.begin()+2,s.begin()+8)]+string(s.begin()+8,s.end()); cout<<code<<"\n"; } }
signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); #ifdef LOCAL cout.setf(ios::unitbuf); #endif
Solve(); return 0; }
|
心路历程(WA,TLE,MLE……)