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)
上一篇:Azkaban进阶之JavaProcess任务类型


下一篇:牛客寒假6