其实题目已经给了模拟思路了:
- 计算数据码字、填充码字和长度码字(注意特判s==-1的时候)
- 计算校验码字,主要是一个多项式求余
数据码字
- 按题意模拟,解析字符串,得到编码值,如果长度是奇数就在加个29
- 两两合并
- 增加填充码字(使得总个数%w==0)
- 增加长度码字
校验码字
- 这题难点就在怎么多项式求余,还好数据比较松可以O(N^2)模拟竖式除法
- 需要用一个多项式乘法求出gx的系数(求的过程中模929,否则会爆)
- fx/gx多项式除法,用一个vector记录对应位置的系数
- 注意除法余项的系数取反 ,因为题目给的-rx
#include<bits/stdc++.h>
using namespace std;
typedef int Module;
typedef enum{
UPPER,
LOWER,
DIGIT,
} MODE;
vector<Module> modules, g, rx;
int w, s;
int n, k;
const int MOD = 929;
string text;
void getModules(const string& t){
MODE m = UPPER;
int n = t.size();
for (int i = 0; i < n;i++){
switch(m){
case UPPER:
if(islower(t[i])){
modules.push_back(27);
modules.push_back(t[i] - 'a');
m = LOWER;
} else if(isdigit(t[i])){
modules.push_back(28);
modules.push_back(t[i] - '0');
m = DIGIT;
} else{
modules.push_back(t[i] - 'A');
}
break;
case LOWER:
if(isupper(t[i])){
modules.push_back(28);
modules.push_back(28);
modules.push_back(t[i] - 'A');
m = UPPER;
} else if(isdigit(t[i])){
modules.push_back(28);
modules.push_back(t[i] - '0');
m = DIGIT;
} else{
modules.push_back(t[i] - 'a');
}
break;
case DIGIT:
if(isupper(t[i])){
modules.push_back(28);
modules.push_back(t[i] - 'A');
m = UPPER;
} else if(islower(t[i])){
modules.push_back(27);
modules.push_back(t[i] - 'a');
m = LOWER;
} else{
modules.push_back(t[i] - '0');
}
break;
}
}
int size = modules.size();
if(size&1){
modules.push_back(29);
size++;
}
for (int i = 0; i < size;i+=2){
int j = i / 2;
modules[j] = modules[i] * 30 + modules[i + 1];
}
modules.resize(size / 2);
n = modules.size() + 1;
k = pow(2, s + 1);
if(s == -1){
if(n % w){
int fill = w - n % w;
n += fill;
for (int i = 0; i < fill;i++){
modules.push_back(900);
}
}
} else{
if((n + k) % w){
int fill = w - (n + k) % w;
n += fill;
for (int i = 0; i < fill;i++){
modules.push_back(900);
}
}
}
modules.insert(modules.begin(), n);
}
void calcGx(){
g = vector<Module>(k + 1, 0);
g[k] = -3;
g[k - 1] = 1;
int pow3 = -9;
for (int i = 0; i < k - 1;i++){
vector<Module> tt(k + 1, 0);
for (int j = k - i - 1; j <= k;j++){
tt[j] = g[j];
}
for (int j = k - i - 1; j <= k;j++){
g[j] = (g[j] % MOD) * pow3 % MOD;
}
for (int j = k - i - 1; j < k;j++){
g[j] = (g[j] + tt[j + 1]) % MOD;
}
g[k - i - 2] = 1;
pow3 *= 3;
pow3 %= MOD;
}
}
void calcRx(){
vector<Module> &gx = g;
vector<Module> dx(modules.size() + k, 0);
for (int i = 0; i < modules.size();i++){
dx[i] = modules[i] % MOD;
}
for (int i = 0; i < modules.size();i++){
int t = dx[i];
for (int j = 0; j < gx.size();j++){
dx[i + j] = (dx[i + j] - gx[j] * t % MOD) % MOD;
}
}
for (int i = dx.size() - gx.size() + 1; i < dx.size();i++){
if(-dx[i] < 0)
rx.push_back(MOD + (-dx[i] % MOD));
else
rx.push_back(-dx[i] % MOD);
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> w >> s;
cin >> text;
getModules(text);
calcGx();
calcRx();
for (int i = 0; i < modules.size();i++){
cout << modules[i] << "\n";
}
if(s != -1){
for (int i = 0; i < rx.size();i++){
cout << rx[i] << "\n";
}
}
return 0;
}
|