CCF-CSP认证 202112-3 登机牌条码(90分)
不算很难的大模拟,考试的时候没做血亏。。不知道代码哪里有问题一直是90分,希望有大佬指出代码哪里有问题QAQ
首先s = -1的情况很容易,维护一个变量mode表示当前模式,直接根据题意模拟即可。关键在于校验码。仔细观察这实际上就是一个多项式除法,用\(g(x)\)去除\(x^kd(x)\)得到的余式加个负号就是\(r(x)\)。所以首先需要把\(g(x)\)展开。注意到\(g(x)\)的每个因式的次数都是1,所以可以直接写\(O(n^2)\)的算法,维护当前展开的部分即可(可以手动模拟一下这个过程)。多项式除法同样直接模拟。坑点在于负数取模,题目应该是采用python对于负数取模的方式(而非C++的方式),因此这里需要手动写一下。python不需要考虑运算时取模,但是喜提TLE导致只有80分,改好的C++代码不知道哪里错了只有90分~
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define mod 929
using namespace std;
int w, s, k, mode = 0;
string ss;
int fpow(int a, int b) {
int ans = 1;
for(; b; b >>= 1) {
if(b & 1) ans = ans * a;
a = a * a;
}
return ans;
}
void getgx(int k, int base, vector<int>& gx) {
base %= mod;
for(int i = 1; i <= k; i++) {
if(i == 1) {
gx.pb(1);
gx.pb(base % mod);
} else {//gx每个因式的系数为1,所以可以很方便的算出来
base = base * 3 % mod;
gx.pb(gx[gx.size() - 1] % mod * base % mod);
for(int i = gx.size() - 2; i > 0; i--) {
gx[i] %= mod;
gx[i] = (gx[i] + base * gx[i - 1] % mod + mod) % mod;
}
}
}
}
signed main() {
cin >> w >> s;
k = fpow(2, s + 1);
cin >> ss;
//cout << ss << endl;
vector<int> op;
for(int i = 0; i < ss.size(); i++) {
char c = ss[i];
if(c >= 'a' && c <= 'z') {
if(mode != 1) {
op.pb(27);
}
op.pb(c - 'a');
mode = 1;
} else if(c >= 'A' && c <= 'Z') {
if(mode != 0) {
if(mode == 1) {
op.pb(28);
}
op.pb(28);
}
op.pb(c - 'A');
mode = 0;
} else {
if(mode != 2) {
op.pb(28);
}
op.pb(c - '0');
mode = 2;
}
}
if(op.size() % 2 == 1) {
op.pb(29);
}
vector<int> word;
for(int i = 0; i < op.size(); i += 2) {
word.pb(30 * op[i] + op[i + 1]);
}
if(s == -1) {
int now = word.size() + 1;
if(now % w != 0) {
for(int i = 0; i < w - now % w; i++) {
word.pb(900);
}
}
cout << word.size() + 1 << endl;
for(auto x : word) {
cout << x << endl;
}
return 0;
}
int now = word.size() + 1 + k;
if(now % w != 0) {
for(int i = 0; i < w - now % w; i++) {
word.pb(900);
}
}
vector<int> d = word;
int tmp = d.size() + 1;
d.insert(d.begin(), tmp % mod);
vector<int> gx;
int base = -3;
getgx(k, base, gx);
for(int i = 0; i < k; i++) {
d.pb(0);
}
for(int i = 0; i < d.size() - 1 - gx.size() + 1 + 1; i++) {
if(d[i] == 0) continue;
for(int j = gx.size() - 1; j >= 0; j--) {
d[i + j] %= mod;
d[i + j] = (d[i + j] + mod - gx[j] * d[i] % mod) % mod;
}
}
for(int i = 0; i < d.size(); i++) {
if(d[i] != 0) {
d[i] = -d[i];
if(d[i] > 0) d[i] %= mod;
else {
d[i] = abs(floor(1.0 * d[i] / 929) * 929 - d[i]);
}
word.pb(d[i] % mod);
}
}
word.insert(word.begin(), tmp);
for(auto x : word) {
cout << x << endl;
}
return 0;
}
mod = 929
def fpow(a, b):
ans = 1
while(1):
if b == 0:
break
if b & 1 == 1:
ans = ans * a
a = a * a
b >>= 1
return ans
def getgx(k, base, gx):
for i in range(1, k + 1):
if i == 1:
gx.append(1)
gx.append(base)
else:
base *= 3
gx.append(gx[-1] * base)
for i in range(len(gx) - 2, 0, -1):
gx[i] = (gx[i] + base * gx[i - 1])
def main():
w, s = map(int, input().split())
k = fpow(2, s + 1)
ss = input()
mode = 0
op = []
mod = 929
for c in ss:
if c.islower():
if mode != 1:
op.append(27)
op.append(ord(c) - ord('a'))
mode = 1
elif c.isupper():
if mode != 0:
if mode == 1:
op.append(28)
op.append(28)
op.append(ord(c) - ord('A'))
mode = 0
else:
if mode != 2:
op.append(28)
op.append(ord(c) - ord('0'))
mode = 2
if len(op) % 2 == 1:
op.append(29)
word = []
for i in range(0, len(op), 2):
word.append(30 * op[i] + op[i + 1])
if s == -1:
now = len(word) + 1
if now % w != 0:
for i in range(w - now % w):
word.append(900)
print(len(word) + 1)
for x in word:
print(x)
return
now = len(word) + 1 + k
if now % w != 0:
for i in range(w - now % w):
word.append(900)
d = word.copy()
tmp = len(d) + 1
d.insert(0, tmp)
gx = []
base = -3
getgx(k, base, gx)
for i in range(k):
d.append(0)
for i in range(0, len(d) - 1 - len(gx) + 1 + 1):
if d[i] == 0:
continue
for j in range(len(gx) - 1, -1, -1):#要倒着处理 否则d[i]一开始就被更新为0了
d[i + j] = (d[i + j] - gx[j] * d[i])
#print(*d)
for i in range(len(d)):
if d[i] != 0:
d[i] = -d[i]
d[i] = (d[i] % 929)
word.append(d[i])
word.insert(0, tmp)
for i in range(len(word)):
print(word[i])
if __name__ == "__main__":
main()
# print(len(word) + 1)
# for x in word:
# print(x)
# ord('a') chr(65)