您的位置:首页 > 其它

判断一个整系数高阶方程的无理根的个数(区域赛)

2016-05-02 11:27 309 查看
题目链接:点击打开链接

这是一道区域赛的题目,涉及到高等代数,这个题目有一点好的就是它给出了根的范围,下面上一个定理:如果方程f(x)=0的系数都是整数,那么方程有理根仅能是这样的分数p/q,其分子p是方程常数项的约数,分母q是方程最高次项的约数。这里最高次系数为1,那么有理根就一定为整数。这里的最高次项的系数为1,所以其有理根一定是整数,所以直接枚举就可以了。最后一个知识,就是判断重根,这个我也是刚刚听说过,具体流程就是求导把原来的根往里面代,如果为零,就是重根。下面是百度到的:

f(x)是x的多项式,fm'(x)是f(x)的m阶导数
f(a)=f'(a)=0,f''(a)≠0,f(a)有二重重根
f(a)=f'(a)=f''(a)=..=fm'(a)=0,fm'(a)≠0,f(a)有m重重根

其实为啥求导求重根我也不是怎么理解,以后再看看书(高等代数),问问别人,查查资料吧,下面上代码:

#include <bits/stdc++.h>

#include <iostream>

#include <algorithm>

using namespace std;

typedef long long LL;

const int maxm = 55;

const LL MOD = 999999997;

const double eps = 1e-8;

inline LL read()

{

    int  c=0,f=1;

    char ch=getchar();

    while(ch<'0'||ch>'9')

    {

        if(ch=='-')f=-1;

        ch=getchar();

    }

    while(ch>='0'&&ch<='9')

    {

        c=c*10+ch-'0';

        ch=getchar();

    }

    return c*f;

}

int gcd(int a,int b)

{

    return b==0?a:gcd(b,a%b);

}

int Eular(int n)

{

    int ret =1;

    for(int i=2; i*i<=n; ++i)

    {

        if(n%i==0)

        {

            ret *= (i-1);

            n/=i;

            while(n%i==0)

            {

                ret*=i;

                n/=i;

            }

        }

    }

    if(n>1) ret*=(n-1);

    return ret;

}

int Get_divisor_sum(int n)

{

    int sum=0;

    for(int i=2; i*i<=n; ++i)

4000
    {

        if(n%i==0)

        {

            sum+=i;

            if(n/i!=i) sum+=n/i;

        }

    }

    sum++;

    return sum;

}

LL Quick_Mod(LL a,LL b)

{

    LL ans=a,ret=1;

    while(b)

    {

        if(b&1) ret = ret*ans;

        b>>=1;

        ans=ans*ans;

    }

    return ret;

}

LL bitwei(LL x)

{

    LL s=0;

    while(x)

    {

        if(x%2) s++;

        x/=2;

    }

    return s;

}

int ac[233],bc[233], n;

int main()

{

    // freopen("1.txt","r",stdin);

    n=read();

    for(int i=1; i<=n; ++i) bc[i]=read(); ///系数

    bc[0]=1;

    int ans=0;

    for(int r=-10; r<=10; ++r) ///枚举正整数根的个数

    {

        for(int j=0; j<=n; j++) ac[j]=bc[j];

        LL sum=0;

        for(int i=0; i<=n; ++i)

        {

            sum+=ac[i]*Quick_Mod(r,n-i);

        }

        if(sum==0)

        {

            ans++;

            for(int k=0; k<n; ++k)  ///求导

            {

                for(int j=n; j>=0; --j)

                {

                    ac[j]*=(n-j-k);

                }

                LL sum=0;

                for(int j=0; j<=n-k-1; ++j)

                {

                    sum+=ac[j]*Quick_Mod(r,n-j);

                }

                if(sum==0) ans++;

                else break;

            }

        }

    }

    printf("%d\n",n-ans);

    return 0;

}

先背着代码跑吧,以后再理解理解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: