• CCFCSP认证 2021123 登机牌条码(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)
    
  • 相关阅读:
    【Log Explorer】查看和恢复数据库数据
    【MSMQ】消息队列(Message Queue)简介及其使用
    【核心对象】我心目中的Asp.net核心对象
    【SQL Server】CROSS APPLY和OUTER APPLY的应用详解
    【批处理】时间处理
    15件事造就有理想的程序员
    IE8下定义IE=EmulateIE7与IE=7的区别
    【批处理】创建快捷方式
    Ghost备份出错导致磁盘空间被占用
    【AJAX】反向Ajax第1部分:Comet介绍
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/15924574.html
Copyright © 2020-2023  润新知