做CSP202112-3 登机牌条码这道题时,卡在了求校验码上(不过还好,不算校验码还能骗到40分呢哈哈~),本着满分的态度,本人思索良久,后经高人提点,意识到求校验码用到了一元多项式除法,鉴于网上的代码过于繁琐(不是我写的看不下去),遂DIY了一份,供大家参考
一、算法设计思想
模拟手算
二、算法流程
三、完整代码
#include<bits/stdc++.h>
using namespace std;
struct polynomial {
int base, exp;
}temp;
vector<polynomial> sub(vector<polynomial> be_s, vector<polynomial> s) {
vector<polynomial> ans;
int i = 0, j = 0;
while (i < be_s.size() && j < s.size()) {
if (s[j].exp > be_s[i].exp) {
temp.base = be_s[i].base;
temp.exp = be_s[i].exp;
ans.push_back(temp);
i++;
}
else if (s[j].exp == be_s[i].exp) {
temp.base = be_s[i].base - s[j].base;
temp.exp = s[j].exp;
if(temp.base!=0)
ans.push_back(temp);
i++;j++;
}
}
return ans;
}
vector<polynomial> mul(vector<polynomial> be_m,polynomial m) {
vector<polynomial> ans = be_m;
for (int i = 0; i < ans.size(); i++) {
ans[i].base *= m.base;
ans[i].exp += m.exp;
}
return ans;
}
int main() {
int m, n;
cin >> m >> n;
//初始化被除数与除数
vector<polynomial> be_div, div;
for (int i = 0; i <= m; i++) {
cin >> temp.base; temp.exp = i;
be_div.push_back(temp);
}
for (int i = 0; i <= n; i++) {
cin >> temp.base; temp.exp = i;
div.push_back(temp);
}
//计算商和余数
vector<polynomial> ans,rem;//ans暂存商,rem暂存余数
polynomial mu;//mu暂存乘数
vector<polynomial> di;//di暂存除数
rem = be_div;
while ((--rem.end())->exp>=n){
mu.exp = (--rem.end())->exp - n;
mu.base = (--rem.end())->base / (--div.end())->base;
ans.push_back(mu);
di = mul(div, mu);
rem = sub(rem, di);
}
for (int i = 0; i < rem.size(); i++) {
cout << rem[i].base << " " << rem[i].exp << endl;
}
return 0;
}
四、测试数据
数据描述
给定一个 m次多项式 F(x)(被除数)和一个 n 次多项式G(x) (除数) ,求出多项式 Q(x)(商), R(x)(余数),满足以下条件:
- Q(x) 次数为 n-m,R(x) 次数小于 m
- F(x) = Q(x) * G(x) + R(x)
第一行两个整数 n,m,意义如上。
第二行 n+1 个整数,从低到高表示 F(x) 的各个系数。
第三行 m+1 个整数,从低到高表示 G(x) 的各个系数。
分别输出余数多项式每一项的系数与指数
【输入】
3 2
3 3 2 1
1 1 1
【输出】
2 0
1 1
(即:2+x)