gplt 团体程序设计天梯赛 多项式A除以B(模拟)

20 篇文章 0 订阅
13 篇文章 0 订阅


5-10 多项式A除以B   (25分)

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

解题思路:

这道题赛时没仔细看,看着大家都跳了,我也跟着跳了,结果最后一小时一分也没出2333

重现后仔细一看,想起了初中自己yy出来的多项式除法,当时好像是为了因式分解所以想出这个东西的。然后表示很吐血,赛时做一下怎么也能拿分吧。

具体做法模拟多项式除法去做就好了,如果不知道多项式除法的可以去看百科,或者看我的程序。

然后坑点就在判0了,我一开始被示例 误导以为0项都在最后面,所以我判0直接从最后开始,然后果断丢了10分,改下就过了。


代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
struct node
{
    double a;
    int mi;
}x[maxn], y[maxn], q[maxn], r[maxn], dif[maxn];
int n, m, z;
void mod()
{
     int o, p,  e=0, i, j, k=0, m1, m2;
     i=j=0;
     m1=x[0].mi;
     m2=y[0].mi;
//     cout<<m1<<" "<<m2<<endl;
     while(m1>m2 ||(m1==m2 && fabs(x[0].a-0)>=0.1))
     {
//         printf("m1 %d m2 %d\n", m1, m2);
        q[k].mi=m1-m2;
        q[k].a=r[0].a/y[0].a;//得到商 
        i=0;
        for(e=1; e<m; e++) //减数多项式
        {
            dif[e].mi=q[k].mi+y[e].mi; //mi相加
            dif[e].a=q[k].a*y[e].a;
//            printf("%.2lf %.2lf %.2lf %d %d %d\n", dif[e].a, q[k].a, y[e].a,  dif[e].mi, q[k].mi, y[e].mi);
        }
        o=1;
        p=1;
        i=0;
        while(p<n && o<m)
        {
            
            if(r[p].mi>dif[o].mi) //被除数mi大
            {
                x[i]=r[p];
                p++;
            }
            else if(r[p].mi==dif[o].mi)//mi相等则相减
            {
                x[i].mi=r[p].mi;
                x[i].a=r[p].a-dif[o].a;
                p++,o++;
            }
            else //除数mi大
            {
                x[i]=dif[o];
                x[i].a=-dif[o].a;
                o++;
            }
            i++;
        }
     if(p<n)
     {
        for(; p<n; p++)x[i++]=r[p];
     }
     else
     {
        for(; o<m; o++)
        {
            x[i].a=-dif[o].a;
            x[i].mi=dif[o].mi;
            i++;
        }
     }
        if(i==0)
        {
            x[i].a=0.0;
            x[i].mi=0;
            i++;
        }
        n=i;
        
        for(i=0; i<n; i++)
        {
            r[i]=x[i];
//            printf("%.1lf %d\n", x[i].a, x[i].mi);
        }
        m1=x[0].mi; 
        k++;
     }
     z=k;
     return;
}
int main()
{
    cin>>n;
    int i, j=0;
    for(i=0; i<n; i++)
    {
        scanf("%d%lf", &x[j].mi, &x[j].a);
        /*
        while(j>0 && x[j-1].mi>x[j].mi+1)
        {
            x[j+1]=x[j];
            x[j].mi=x[j-1].mi-1;
            x[j].a=0.0;
            j++;
        }
        */
        r[j].a=x[j].a; 
        r[j].mi=x[j].mi;
        j++;
    }
    cin>>m;
    for(i=0; i<m; i++)
    {
        scanf("%d%lf", &y[i].mi, &y[i].a);
    }
    mod();   
    int count=z;
    for(i=0; i<z; i++)if(fabs(q[i].a)<0.1)count--;
    cout<<count;
    for(i=0; i<z; i++)if(!(fabs(q[i].a)<0.1))printf(" %d %.1lf", q[i].mi, q[i].a);    
    if(count==0)printf(" 0 0.0\n");
    else printf("\n");
    count=n;
    for(i=0; i<n; i++)if(fabs(r[i].a)<0.1)count--;
    
    printf("%d", count);
    if(count==0)printf(" 0 0.0\n");
    for(i=0; i<n; i++)if(!(fabs(r[i].a)<0.1))printf(" %d %.1lf", r[i].mi, r[i].a);

}
/*
2 1 2 0 1
1 0 2
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值