团体程序设计天梯赛-练习集 -- L2-018. 多项式A除以B(多项式除法--模拟)

题意:

给你两个多项式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

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越

这仍然是一道关于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

提交代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值