POJ 1166 高斯消元 疑惑的思考

来源:互联网 发布:淘宝怎么邮费退款 编辑:程序博客网 时间:2024/05/16 14:22

不知道为什么消元的时候没选择绝对值最大的那一列就不会wa了

可能是刚好避开了数据吧觉得

可能刚好选择到每个a(i,i)=1 ,a(i,i)=3 (即a(i,i)=2 时就会出错)的那一行


已知p是素数时,模p剩余系里每个除0以外的元素都有唯一的逆。

模4时,由于4不是素数,所以不会有唯一的逆,比如2就没有逆

当在消元化简到 ax=b(mod 4) 我们枚举x=0,1,2,3可能都没有解

这是因为线性模方程 ax=b(mod n)  -> ax-ny=b ,  d=(a,n) ,  当 b%d!=0 时是没有解的

而当n是素数,d=(a,n)=1,b%d=0,肯定有解


事先算好这个矩阵的逆(在模4时同样可能出错)后直接乘得到结果觉得应该也可以过

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <map>#include <set>#include <algorithm>#include <ctime>#include <vector>#include <string>using namespace std;int a[9][10]={{1,1,0,1,0,0,0,0,0,0},{1,1,1,0,1,0,0,0,0,0},{0,1,1,0,0,1,0,0,0,0},{1,0,0,1,1,0,1,0,0,0},{1,0,1,0,1,0,1,0,1,0},{0,0,1,0,1,1,0,0,1,0},{0,0,0,1,0,0,1,1,0,0},{0,0,0,0,1,0,1,1,1,0},{0,0,0,0,0,1,0,1,1,0}};int p=4;int ans[100];int gcd(int a,int b){    return b==0 ? a: gcd(b,a%b);}int lcm(int a,int b){    return a/gcd(a,b)*b;}int main (){    for(int i=0;i<9;++i)    {        scanf("%d",&a[i][9]);        a[i][9]=(4-a[i][9])%4;    }    int mul,ma,mb;    for(int i=0;i<9;++i)    {        if(a[i][i]==0)        {            for(int k=i+1;k<9;++k)                if(a[k][i])                {                    for(int j=0;j<=9;++j)                        swap(a[k][j],a[i][j]);                    break;                }        }        for(int k=i+1;k<9;++k)            if(a[k][i])        {            ma=a[k][i];            mb=a[i][i];            for(int j=i;j<=9;++j)            {                a[k][j]=a[k][j]*mb-a[i][j]*ma;                a[k][j]=(a[k][j]%4+4)%4;            }        }    }    int sum=0;    for(int i=8;i>=0;--i)    {        for(int k=i+1;k<9;++k)        {            a[i][9]-=ans[k]*a[i][k];            a[i][9]=(a[i][9]%4+4)%4;        }        for(ans[i]=0;ans[i]<=3;ans[i]++)        {            if((a[i][i]*ans[i]%4+4)%4==a[i][9])                break;        }        ans[i]%=4;        sum+=ans[i];    }    int j=0,cnt=0;;    while(j<9)    {        if(ans[j])        {            printf("%d",j+1);            cnt++;            if(cnt<sum)                printf(" ");            else printf("\n");            ans[j]--;        }        else j++;    }    return 0;}