CSP-24-3 登机牌条码
大模拟 + 多项式除法
原题链接: https://www.acwing.com/problem/content/4285/
这道大模拟和以往的不太一样,模拟部分很简单,难点在于多项式除法部分。
对于下面的描述,如何看出要求的是多项式除法呢?
因为 xk、g(x)、d(x)均已知,要求q(x)和r(x),这就相当于被除数xk * d(x)已知,在同余条件下,除数g(x)也已知,要去求商q(x)和余数r(x)。
那么如何进行多项式的除法呢?
以这一题为例,其实多项式除法就类似于正常数的除法,不同点在于:
1.每次消除被除数的最高位,确保处理后的除数的最高项的次数和系数与被除数的最高项的次数和系数分别相等。其实这就确定了每一步的商。
2.在除法运算的过程中,在每一次除法结束后停止,都能保证正确。比如,除法运行两次后,得到部分商 12x^2 - 3x,部分余数 5x + 1,将部分商和部分余数带回原始中,能保证原式的等式仍成立。
题目要求:r是不高于k-1次的多项式,所以我们需要余数到 k - 1 次时就停下来。
PS: vector
vector也有insertAPI,通常,第一个参数是插入位置(迭代器表示),第二个参数是插入的内容。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MOD = 929;
int w, s;
string str;
vector<LL> code;
vector<LL> v;
// 0 小写 1 大写 2 数字
int st = 1;
bool is_Bigchar(char c) {
if (c <= 'Z' && c >= 'A')
return true;
return false;
}
bool is_Smallchar(char c) {
if (c <= 'z' && c >= 'a')
return true;
return false;
}
bool is_Number(char c) {
if (c <= '9' && c >= '0')
return true;
return false;
}
int main() {
cin >> w >> s;
cin >> str;
int len_s = (s == -1 ? 0 : (int)pow(2, s + 1));
for (int i = 0; i < str.size(); i++) {
if (st == 0) {
if (is_Bigchar(str[i])) {
v.push_back(28);
v.push_back(28);
st = 1;
v.push_back((int)(str[i] - 'A'));
} else if (is_Smallchar(str[i])) {
v.push_back((int)(str[i] - 'a'));
} else {
v.push_back(28);
v.push_back((int)(str[i] - '0'));
st = 2;
}
} else if (st == 1) {
if (is_Bigchar(str[i])) {
v.push_back((int)(str[i] - 'A'));
} else if (is_Smallchar(str[i])) {
v.push_back(27);
v.push_back((int)(str[i] - 'a'));
st = 0;
} else {
v.push_back(28);
v.push_back((int)(str[i] - '0'));
st = 2;
}
} else if (st == 2) {
if (is_Bigchar(str[i])) {
v.push_back(28);
v.push_back((int)(str[i] - 'A'));
st = 1;
} else if (is_Smallchar(str[i])) {
v.push_back(27);
v.push_back((int)(str[i] - 'a'));
st = 0;
} else {
v.push_back((int)(str[i] - '0'));
}
}
}
if ((int)(v.size()) % 2 != 0) {
v.push_back(29);
}
for (int i = 0; i < v.size(); i += 2) {
code.push_back(v[i] * 30 + v[i + 1]);
}
int tmp_l = ((int)code.size() + 1 + len_s) % w;
if (tmp_l != 0) {
for (int i = 0; i < w - tmp_l; i++) {
code.push_back(900);
}
}
code.insert(code.begin(), (int)code.size() + 1);
int n = code.size();
int k = len_s;
vector<LL> d(n + len_s, 0);
vector<LL> g(n + len_s, 0);
for (int i = 0; i <= n - 1; i++) {
d[n + k - 1 - i] = code[i] % MOD;
}
g[0] = 1;
int g_top = 0; //gx函数的最高次项
int exp = 1;
vector<int> mul(2);
mul[1] = 1;
for (int i = 0; i < k; ++ i) {
vector<LL> tmp(n + k, 0);
exp = (exp * 3 ) % MOD;
mul[0] = -exp;
for (int j = 0; j <= g_top ; ++j)
for (int l = 0; l <= 1; ++ l) {
tmp[j + l] = (tmp[j + l] % MOD + (g[j] % MOD) * (mul[l] % MOD) ) % MOD;
}
g = tmp;
g_top += 1;
}
/*
多项式除法
*/
int d_top = n + len_s - 1;
while (d_top >= len_s) {
int div = d[d_top] / g[g_top];
for (int i = 0; i <= g_top; i++) {
d[d_top - i] = ((d[d_top - i] % MOD) - (div % MOD) * (g[g_top - i] % MOD)) % MOD;
}
d_top--;
}
for (int i = k - 1; i >= 0; i--) {
code.push_back(((-d[i] % MOD) + MOD) % MOD);
}
for (int i = 0; i < code.size(); i++) {
printf("%d\n", code[i]);
}
return 0;
}
参考博客:
本文作者:superPG
本文链接:https://www.cnblogs.com/superPG/p/16317138.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步