jzoj 4831. 【NOIP2016提高A组集训第3场10.31】方程式 多项式除法 数学

来源:互联网 发布:板式家具设计拆单软件 编辑:程序博客网 时间:2024/05/29 10:12

题意

给出一个n次方程,保证这个方程的所有根都为1到20之间的正整数,请把该方程所有的根从小到大输出,若一个根出现了x次则要输出x次该根。
n<=7

分析

第一眼看题的时候没看到重根也要输出,就以为是一道只要枚举一下就好的傻逼题,看到重根之后就没什么思路了。
后来回想了一下一元二次方程的解法,想起了可以把原方程分解成(x-x1)(x-x2)=0的形式,那么推广一下,一元n次方程同样也可以分解成为(x-x1)(x-x2)…(x-xn)=0的形式,那么我们只要每次枚举一个最小的根xi,然后把原多项式除以(x-xi),就相当于消去了一个根,直到整个多项式被除尽位置。

第一次写多项式除法,没想到还挺好写的。

代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define ll long longusing namespace std;int a[10],n;bool check(int x){    ll w=1;    ll ans=0;    for (int i=n+1;i>=1;i--)    {        ans+=w*a[i];        w=w*x;    }    if (ans==0) return 1;    else return 0;}void divi(int x1,int y1){    int x2=a[1],y2=a[2];    for (int i=2;i<=n+1;i++)    {        a[i-1]=x2/x1;        x2=y2-y1*x2/x1;        y2=a[i+1];    }}int main(){    freopen("equation.in","r",stdin);    freopen("equation.out","w",stdout);    scanf("%d",&n);    for (int i=n+1;i>=1;i--)        scanf("%d",&a[i]);    for (int i=1;i<=20;i++)        if (check(i))        {            printf("%d ",i);            divi(1,-i);            n--;            if (n==0) break;            i=0;        }    return 0;}
1 0
原创粉丝点击