1. 程式人生 > 實用技巧 >習題:Guess the Root(高斯消元)

習題:Guess the Root(高斯消元)

題目

傳送門

思路

阿這

基本上就是暴力用高斯消元來搞就行了

因為\(mod\)很小,所以可以直接列舉\(x\)

程式碼

#include<iostream>
using namespace std;
const int mod=1e6+3;
int n=11;
long long a[15][15];
long long f_abs(long long x)
{ 
    return x<0?-x:x;
}
long long qkpow(int a,int b)    
{
    if(b==0)
        return 1;
    if(b==1)
        return a;
    long long t=qkpow(a,b/2);
    t=t*t%mod;
    if(b%2==1)
        t=t*a%mod;
    return t;
}
int main()
{
    for(int i=1;i<=n;i++)
    {
        cout<<"? "<<i-1<<endl;
        cin>>a[i][n+1];
        for(int j=1;j<=n;j++)
            a[i][j]=qkpow(i-1,j-1); 
    }
    for(int i=1;i<=n;i++)
    {
        int _ind=i;
        for(int j=i+1;j<=n;j++)
            if(f_abs(a[j][i])>f_abs(a[_ind][i]))
                _ind=j;
        swap(a[_ind],a[i]);
        if(a[i][i]==0)
        {
            cout<<"! -1";
            return 0;   
        }
        for(int j=1;j<=n;j++)
        {
            if(j!=i)
            {
                long long t=a[j][i]*qkpow(a[i][i],mod-2);
                for(int k=i+1;k<=n+1;k++)
                {
                    a[j][k]=((a[j][k]-t*a[i][k])%mod+mod)%mod;
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
    { 
        a[i][i]=a[i][n+1]*qkpow(a[i][i],mod-2)%mod;
	} 
	for(int i=0;i<mod;i++)
    {
        long long t=0;
        for(int j=1;j<=n+1;j++)
        {
            t=(t+qkpow(i,j-1)*a[j][j]%mod)%mod;
            //cout<<qkpow(i,j-1)<<' '<<a[j][j]<<endl;
        }
        //cout<<endl;
        if(t==0)
        {
            cout<<"! "<<i;
            return 0;
        }
    }
    cout<<"! -1";
    return 0;
}