【枚舉】【高斯消元】Gym - 101412D - Find the Outlier
阿新 • • 發佈:2017-07-26
void while ... () fine blog 個數 i+1 find
給你一個未知的d次多項式在0,1,...,d+2處的取值,其中有且只有一個是錯的,問你哪個是錯的。
枚舉哪個是錯的,再在剩下的d+2個中取d+1個高斯消元,解出多項式系數,然後代一下最後剩下的那個數看看是否合法,如果合法再看看那個錯的是否真的錯了。
#include<cstdio> #include<cmath> #include<algorithm> #include<cstring> using namespace std; #define N 11 double v[N]; int n; double B[N][N+1],A[N][N+1],x[N],b[N]; double sqr(double x){return x*x;} void guass_jordan() { memcpy(B,A,sizeof(A)); for(int i=1;i<=n;++i) B[i][n+1]=b[i]; for(int i=1;i<=n;++i)//枚舉:正在消除第i個未知數,之後第i個方程廢掉,矩陣行、列-1 { int pivot=i; for(int j=i+1;j<=n;++j)//枚舉j:把正在處理的未知數的系數的絕對值最大的方程換到第i行 if(fabs(B[j][i])>fabs(B[pivot][i])) pivot=j; swap(B[i],B[pivot]); //if(fabs(B[i][i])<EPS) //若所有(最大)的該未知數系數為0,說明少一個未知數,有無窮多解 for(int j=i+1;j<=n+1;++j) B[i][j]/=B[i][i]; for(int j=1;j<=n;++j) if(i!=j)//枚舉所有的方程,從第j個方程中消去第i個未知數 for(int k=i+1;k<=n+1;++k)//依次把第j個方程中的第k個未知數減去應減的數值 B[j][k]-=B[j][i]*B[i][k]; } for(int i=1;i<=n;++i) x[i]=B[i][n+1]; } int d; int main(){ while(1){ scanf("%d",&d); if(!d){ return 0; } memset(B,0,sizeof(B)); memset(A,0,sizeof(A)); memset(x,0,sizeof(x)); memset(b,0,sizeof(b)); n=d+1; for(int i=0;i<=d+2;++i){ scanf("%lf",&v[i]); } for(int i=0;i<=d+2;++i){ for(int j=0;j<=d+2;++j){ if(j!=i){ for(int k=0,l=0;k<=d+2;++k){ if(k!=i && k!=j){ int kk=1; ++l; for(int p=1;p<=d+1;++p){ A[l][p]=(double)kk; kk=kk*k; } b[l]=v[k]; } } guass_jordan(); int jj=1; double tmp=0; for(int k=1;k<=d+1;++k){ tmp+=(double)jj*x[k]; jj*=j; } if(fabs(tmp-v[j])<0.00001){ int ii=1; double tmp2=0; for(int k=1;k<=d+1;++k){ tmp2+=(double)ii*x[k]; ii*=i; } if(fabs(tmp2-v[i])>0.01){ printf("%d\n",i); goto OUT; } } } } } OUT:; } return 0; }
【枚舉】【高斯消元】Gym - 101412D - Find the Outlier