题意:
给你两个多项式A和B,求A/B 的商和余数。
思路:
这个题目 学到了多项式除法 = =,好水。
具体看一下百度百科:
多项式A/B,循环终止条件就是当A的最大指数小于B的最大指数时,这时A就是余数。
否则就一直循环。
怎么除呢:
我们构造出一个式子来,使得B乘以这个式子能等于A的最大指数的那一项,然后把它消掉,一步一步模拟,直到A的最大指数小于B的最大指数。
我们可以利用map 第一项存指数,第二项存系数来模拟。
比较恶心啊,因为要特判进位后的系数是不是0,直接写一个判断函数和输出函数即可。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
#include <cstdlib>
using namespace std;
const double eps = 1e-10;
map<double,double>mp,mp2;
map<double,double>tmp;
map<double,double>::reverse_iterator it,it2;
map<double,double >::iterator it3;
vector<pair<double,double> >ans,ans2;
int dcmp(double a,double b){
if (fabs(a-b) < eps) return 0;
if (a >b ) return 1;
return -1;
}
bool cmp(pair<double,double>& a,pair<double,double>& b){
return dcmp(a.second,b.second) == 1;
}
bool judge(double x){ ///判断系数是不是0
x *= 100;
int ans = (int)x;
double res;
if (ans % 10 >= 5){
ans /= 10;
ans++;
}
else {
ans/=10;
}
int one = ans/10;
int two = ans%10;
return one == 0 && two == 0;
}
void print2(double x){ /// 打印非0项
int flag = 0;
if (dcmp(x,0) == -1) flag = 1, x = -x;
x *= 100;
int ans = (int)x;
double res;
putchar(' ');
if (ans % 10 >= 5){
ans /= 10;
ans++;
}
else {
ans/=10;
}
int one = ans/10;
int two = ans%10;
if (flag) putchar('-');
// if (two == 0) printf("%d",one);
// else
printf("%d.%d",one,two);
}
void print(vector<pair<double,double> >& ans){
sort(ans.begin(),ans.end(),cmp);
int sum = 0;
for (int i = 0; i < ans.size(); ++i){
if (judge(ans[i].first)) continue;
++sum;
}
if (sum == 0) puts("0 0 0.0");
else {
printf("%d",sum);
for (int i = 0; i < ans.size(); ++i){
// if (ans[i].first == 0) continue;
if (judge(ans[i].first))continue;
printf(" %d",(int)ans[i].second);
print2(ans[i].first);
// printf(" %.1f %.1f",ans[i].second,ans[i].first);
}
putchar('\n');
}
}
int main(){
int n, m;
scanf("%d",&n);
for (int i = 0; i < n; ++i){
double x,y;
scanf("%lf %lf",&x, &y);
if (mp.count(x))mp[x] += y;
else mp[x] = y;
}
scanf("%d",&m);
for (int i = 0; i < m; ++i){
double x,y;
scanf("%lf %lf",&x, &y);
if (mp2.count(x))mp2[x] += y;
else mp2[x] = y;
}
while(1){
it = mp.rbegin();
it2 = mp2.rbegin();
double t1 = it->second/it2->second;//xishu;
double t2 = it->first-it2->first;//zhishu;
// printf("%.10f %.10f\n",t1,t2);
// break;
if (dcmp(t2,0) == -1) break;
pair<double,double>p1 = make_pair(t1,t2);
ans.push_back(p1);
tmp.clear();
for (it3 = mp2.begin(); it3 != mp2.end(); ++it3){
double d1 = t1 * it3->second;
double d2 = t2 + it3->first;
if (!tmp.count(d2)) tmp[d2] = d1;
else tmp[d2] += d1;
}
for (it3 = tmp.begin(); it3 != tmp.end(); ){
if (!mp.count(it3->first)){
mp[it3->first] = -(it3->second);
tmp.erase(it3++);
}
else ++it3;
}
for (it3 = mp.begin(); it3 != mp.end(); ){
if (!tmp.count(it3->first)){
++it3;
continue;
}
double o = it3->first;
mp[o ] -= tmp[o ];
if (dcmp(mp[o],0) == 0) mp.erase(it3++);
else ++it3;
}
if (dcmp(t2,0) == 0) break;
}
for (it3 = mp.begin(); it3 != mp.end(); ++it3){
ans2.push_back(make_pair(it3->second,it3->first));
}
print(ans);
print(ans2);
return 0;
}
/**
4 4 1 2 -3 1 -1 0 -1
3 2 3 1 -2 0 1
3 2 0.3 1 0.2 0 -1.0
1 1 -3.1
**/
L2-018. 多项式A除以B
这仍然是一道关于A/B的题,只不过A和B都换成了多项式。你需要计算两个多项式相除的商Q和余R,其中R的阶数必须小于B的阶数。
输入格式:
输入分两行,每行给出一个非零多项式,先给出A,再给出B。每行的格式如下:
N e[1] c[1] ... e[N] c[N]
其中N是该多项式非零项的个数,e[i]是第i个非零项的指数,c[i] 是第i个非零项的系数。各项按照指数递减的顺序给出,保证所有指数是各不相同的非负整数,所有系数是非零整数,所有整数在整型范围内。
输出格式:
分两行先后输出商和余,输出格式与输入格式相同,输出的系数保留小数点后1位。同行数字间以1个空格分隔,行首尾不得有多余空格。注意:零多项式是一个特殊多项式,对应输出为“0 0 0.0”。但非零多项式不能输出零系数(包括舍入后为0.0)的项。在样例中,余多项式其实有常数项“-1/27”,但因其舍入后为0.0,故不输出。
输入样例:4 4 1 2 -3 1 -1 0 -1 3 2 3 1 -2 0 1输出样例:
3 2 0.3 1 0.2 0 -1.0 1 1 -3.1
提交代码