• 高斯消元学习


    POJ1222 http://poj.org/problem?id=1222

    一定有解,直接高斯消元搞定

    1. #include <iostream>  
    2. #include <cmath>  
    3. #include <cstdio>  
    4. #include <cstring>  
    5. using namespace std;  
    6.   
    7. const int maxn =30;  
    8.   
    9. int equ,var;  
    10.   
    11. int a[maxn+1][maxn+1],x[maxn];  
    12.   
    13. void Gauss(){  
    14.     int k,col;  
    15.     for(k=0,col=0;k<equ&&col<var;k++,col++){  
    16.         int mx=k;  
    17.         for(int i=k+1;i<equ;i++)  
    18.             if(a[i][col]>a[mx][col]) mx=i;  
    19.         if(mx!=k)  
    20.             for(int i=col;i<var+1;i++)  
    21.             swap(a[k][i],a[mx][i]);  
    22.         if(!a[k][col]){k--;continue;}  
    23.         for(int i=k+1;i<equ;i++){  
    24.             if(a[i][col]!=0){  
    25.                 for(int j=col;j<var+1;j++)  
    26.                     a[i][j]^=a[k][j];  
    27.             }  
    28.         }  
    29.     }  
    30.     for(int i=var-1;i>=0;i--){  
    31.         int tmp=a[i][var];  
    32.         for(int j=i+1;j<var;j++) tmp^=(a[i][j]&&x[j]);  
    33.         x[i]=tmp;  
    34.     }  
    35. }  
    36.   
    37. void init(){  
    38.     memset(a,0,sizeof(a));  
    39.     memset(x,0,sizeof(x));  
    40.     for(int i=0;i<5;i++){  
    41.         for(int j=0;j<6;j++){  
    42.             if(i!=0) a[i*6+j][(i-1)*6+j]=1;  
    43.             if(i!=4) a[i*6+j][(i+1)*6+j]=1;  
    44.             if(j!=0) a[i*6+j][i*6+j-1]=1;  
    45.             if(j!=5) a[i*6+j][i*6+j+1]=1;  
    46.             a[i*6+j][i*6+j]=1;  
    47.         }  
    48.     }  
    49. }  
    50.   
    51. int main()  
    52. {  
    53.     int t,ca=1;  
    54.     cin>>t;  
    55.     while(t--){  
    56.         init();  
    57.         equ=var=30;  
    58.         for(int i=0;i<30;i++)  
    59.             cin>>a[i][30];  
    60.         Gauss();  
    61.         printf("PUZZLE #%d ",ca++);  
    62.         for(int i=0;i<30;i++)  
    63.         {  
    64.             if(i%6!=0) putchar(' ');  
    65.             printf("%d",x[i]);  
    66.             if(i%6==5) puts("");  
    67.         }  
    68.     }  
    69.     return 0;  
    70. }  

    POJ1681 http://poj.org/problem?id=1681  

    高斯消元推断有没有解,然后二进制枚举自由变元 求最小值

    1. #include <iostream>  
    2. #include <cstring>  
    3. #include <cstdio>  
    4. #include <cmath>  
    5. using namespace std;  
    6.   
    7. const int maxn = 16*16;  
    8.   
    9. int a[maxn][maxn],x[maxn],n;  
    10. int free_num,free_x[maxn],equ,var;  
    11. char mp[20][20];  
    12.   
    13. void init()  
    14. {  
    15.     memset(a,0,sizeof(a));  
    16.     memset(free_x,0,sizeof(free_x));  
    17.     memset(x,0,sizeof(x));  
    18.     free_num=0;  
    19.     for(int i=0;i<n;i++){  
    20.         for(int j=0;j<n;j++){  
    21.             if(i!=0) a[i*n+j][(i-1)*n+j]=1;  
    22.             if(i!=n-1) a[i*n+j][(i+1)*n+j]=1;  
    23.             if(j!=0) a[i*n+j][i*n+j-1]=1;  
    24.             if(j!=n-1) a[i*n+j][i*n+j+1]=1;  
    25.             a[i*n+j][i*n+j]=1;  
    26.         }  
    27.     }  
    28.     equ=var=n*n;  
    29. }  
    30.   
    31. int Gauss()  
    32. {  
    33.     int k,col;  
    34.     for(k=0,col=0;k<equ&&col<var;k++,col++){  
    35.         int mx=k;  
    36.         for(int i=k+1;i<equ;i++)  
    37.             if(a[i][col]>a[mx][col]) mx=i;  
    38.         if(k!=mx){  
    39.             for(int i=col;i<var+1;i++)  
    40.                 swap(a[k][i],a[mx][i]);  
    41.         }  
    42.         if(!a[k][col]){  
    43.             k--;  
    44.             free_x[free_num++]=col;  
    45.             continue;  
    46.         }  
    47.         for(int i=k+1;i<equ;i++){  
    48.             if(a[i][col]!=0){  
    49.                 for(int j=col;j<var+1;j++)  
    50.                     a[i][j]^=a[k][j];  
    51.             }  
    52.         }  
    53.     }  
    54.     for(int i=k;i<equ;i++)  
    55.         if(a[i][col]) return -1;  
    56.     return var-k;  
    57. }  
    58.   
    59. void solve()  
    60. {  
    61.     int t=Gauss();  
    62.     //cout<<"t "<<t<<endl;  
    63.     if(t==-1){  
    64.         printf("inf ");  
    65.         return ;  
    66.     }  
    67.     int ans;  
    68.     if(t==0){  
    69.         ans=0;  
    70.         for(int i=var-1;i>=0;i--){  
    71.             x[i]=a[i][var];  
    72.             for(int j=i+1;j<var;j++)  
    73.                 x[i]^=(a[i][j]&&x[j]);  
    74.             ans+=x[i];  
    75.         }  
    76.     }  
    77.     else{  
    78.         ans=1000000000;  
    79.         /*cout<<"******"<<endl; 
    80.         for(int i=0;i<t;i++) 
    81.             cout<<free_x[i]<<" "; 
    82.         cout<<endl<<"*******"<<endl;*/  
    83.         for(int i=0;i<(1<<t);i++){  
    84.             int tmp=0;  
    85.             for(int j=0;j<t;j++){  
    86.                 if(i&(1<<j)){  
    87.                     x[free_x[j]]=1;  
    88.                     tmp++;  
    89.                 }  
    90.                 else  
    91.                     x[free_x[j]]=0;  
    92.             }  
    93.             for(int j=var-t-1,k;j>=0;j--){  
    94.                 for(k=j;k<var;k++)  
    95.                     if(a[j][k]) break;  
    96.                 x[k]=a[j][var];  
    97.                 for(int l=k+1;l<var;l++)  
    98.                     x[k]^=(a[j][l]&&x[l]);  
    99.                 tmp+=x[k];  
    100.             }  
    101.             ans=min(tmp,ans);  
    102.         }  
    103.     }  
    104.     printf("%d ",ans);  
    105. }  
    106.   
    107. int main()  
    108. {  
    109.     int t;  
    110.     scanf("%d",&t);  
    111.     while(t--){  
    112.         scanf("%d",&n);  
    113.         init();  
    114.         for(int i=0;i<n;i++)  
    115.             scanf("%s",mp[i]);  
    116.         for(int i=0;i<n;i++){  
    117.             for(int j=0;j<n;j++){  
    118.                 if(mp[i][j]=='w')  
    119.                     a[i*n+j][n*n]=1;  
    120.             }  
    121.         }  
    122.         solve();  
    123.     }  
    124.     return 0;  
    125. }  

    POJ 1753 http://poj.org/problem?id=1753

    同上

    1. #include <iostream>  
    2. #include <cstring>  
    3. #include <cstdio>  
    4. using namespace std;  
    5.   
    6. const int maxn = 17;  
    7.   
    8. int equ,var,free_num,free_x[maxn];  
    9. int a[maxn][maxn],x[maxn];  
    10. char mp[4][4];  
    11.   
    12. void init()  
    13. {  
    14.     memset(a,0,sizeof(a));  
    15.     memset(x,0,sizeof(x));  
    16.     var=equ=16;  
    17.     free_num=0;  
    18.     for(int i=0;i<4;i++){  
    19.         for(int j=0;j<4;j++){  
    20.             if(i!=0) a[i*4+j][(i-1)*4+j]=1;  
    21.             if(i!=3) a[i*4+j][(i+1)*4+j]=1;  
    22.             if(j!=0) a[i*4+j][i*4+j-1]=1;  
    23.             if(j!=3) a[i*4+j][i*4+j+1]=1;  
    24.             a[i*4+j][i*4+j]=1;  
    25.         }  
    26.     }  
    27. }  
    28.   
    29. int Gauss()  
    30. {  
    31.     int k,col;  
    32.     for(k=0,col=0;k<equ&&col<var;k++,col++){  
    33.         int mx=k;  
    34.         for(int i=k+1;i<equ;i++)  
    35.             if(a[i][col]>a[mx][col]) mx=i;  
    36.         for(int i=col;i<var+1;i++)  
    37.             swap(a[k][i],a[mx][i]);  
    38.         if(!a[k][col]){  
    39.             k--;  
    40.             free_x[free_num++]=col;  
    41.             continue;  
    42.         }  
    43.         for(int i=k+1;i<equ;i++){  
    44.             if(a[i][col]){  
    45.                 for(int j=col;j<var+1;j++)  
    46.                     a[i][j]^=a[k][j];  
    47.             }  
    48.         }  
    49.     }  
    50.     for(int i=k;i<equ;i++)  
    51.         if(a[i][col]) return -1;  
    52.     return var-k;  
    53. }  
    54.   
    55. int calu()  
    56. {  
    57.     int t=Gauss();  
    58.     //cout<<"t "<<t<<endl;  
    59.     if(t==-1) return -1;  
    60.     int ans;  
    61.     if(t==0){  
    62.         ans=0;  
    63.         for(int i=var-1;i>=0;i--){  
    64.             x[i]=a[i][var];  
    65.             for(int j=i+1;j<var;j++)  
    66.                 x[i]^=(x[j]&&a[i][j]);  
    67.             ans+=x[i];  
    68.         }  
    69.     }  
    70.     else{  
    71.         ans=10000000;  
    72.         for(int i=0;i<(1<<t);i++){  
    73.             int tmp=0;  
    74.             for(int j=0;j<t;j++){  
    75.                 if(i&(1<<j)){  
    76.                     x[free_x[j]]=1;  
    77.                     tmp++;  
    78.                 }  
    79.                 else  
    80.                     x[free_x[j]]=0;  
    81.             }  
    82.             for(int j=var-t-1,k;j>=0;j--){  
    83.                 for(k=j;k<var;k++)  
    84.                     if(a[j][k]) break;  
    85.                 x[k]=a[j][var];  
    86.                 for(int l=k+1;l<var;l++)  
    87.                     x[k]^=(a[j][l]&&x[l]);  
    88.                 tmp+=x[k];  
    89.             }  
    90.             ans=min(ans,tmp);  
    91.         }  
    92.     }  
    93.     return ans;  
    94. }  
    95.   
    96. int main()  
    97. {  
    98.     while(~scanf("%s",mp[0])){  
    99.         scanf("%s%s%s",mp[1],mp[2],mp[3]);  
    100.         init();  
    101.         for(int i=0;i<4;i++){  
    102.             for(int j=0;j<4;j++){  
    103.                 if(mp[i][j]=='w')  
    104.                     a[i*4+j][16]=0;  
    105.                 else  
    106.                     a[i*4+j][16]=1;  
    107.             }  
    108.         }  
    109.         int ans1=calu();  
    110.         init();  
    111.         for(int i=0;i<4;i++){  
    112.             for(int j=0;j<4;j++){  
    113.                 if(mp[i][j]=='b')  
    114.                     a[i*4+j][16]=0;  
    115.                 else  
    116.                     a[i*4+j][16]=1;  
    117.             }  
    118.         }  
    119.         int ans2=calu();  
    120.         //cout<<"ans1  ans2 "<<ans1<<" "<<ans2<<endl;  
    121.         if(ans1>=0&&ans2>=0){  
    122.             cout<<min(ans1,ans2)<<endl;  
    123.         }  
    124.         else{  
    125.             if(ans1<0&&ans2<0)  
    126.                 cout<<"Impossible"<<endl;  
    127.             else  
    128.                 cout<<max(ans1,ans2)<<endl;  
    129.         }  
    130.     }  
    131.     return 0;  
    132. }  


    POJ1830 http://poj.org/problem?id=1830

    求解的方案数 每一个变量有两种取值  则总数为2^x  个 x为自由变量的个数

    1. #include <iostream>  
    2. #include <cstring>  
    3. #include <cstdio>  
    4. #include <cmath>  
    5. using namespace std;  
    6.   
    7. int free_num,n;  
    8. int a[30][30],s[30],e[30],x[30];  
    9. int Gauss()  
    10. {  
    11.     int k,col;  
    12.     for(k=0,col=0;k<n&&col<n;k++,col++){  
    13.         int mx=k;  
    14.         for(int i=k+1;i<n;i++)  
    15.             if(a[mx][col]<a[i][col]) mx=i;  
    16.         if(mx!=k){  
    17.             for(int i=col;i<n+1;i++)  
    18.                 swap(a[k][i],a[mx][i]);  
    19.         }  
    20.         if(!a[k][col]){  
    21.             k--;  
    22.             continue;  
    23.         }  
    24.         for(int i=k+1;i<n;i++){  
    25.             if(a[i][col]!=0){  
    26.                 for(int j=col;j<n+1;j++)  
    27.                     a[i][j]^=a[k][j];  
    28.             }  
    29.         }  
    30.     }  
    31.     for(int i=k;i<n;i++){  
    32.         if(a[i][col]!=0)  
    33.             return -1;  
    34.     }  
    35.     return n-k;  
    36. }  
    37. int main()  
    38. {  
    39.     int t;  
    40.     cin>>t;  
    41.     while(t--){  
    42.         cin>>n;  
    43.         for(int i=0;i<n;i++)  
    44.             cin>>s[i];  
    45.         for(int j=0;j<n;j++)  
    46.             cin>>e[j];  
    47.         int x,y;  
    48.         memset(a,0,sizeof(a));  
    49.         for(int i=0;i<n;i++)  
    50.             a[i][i]=1;  
    51.         while(1){  
    52.             cin>>x>>y;  
    53.             if(x==0&&y==0)  
    54.                 break;  
    55.             a[y-1][x-1]=1;  
    56.         }  
    57.         for(int i=0;i<n;i++)  
    58.             a[i][n]=s[i]^e[i];  
    59.         int free_num=Gauss();  
    60.         if(free_num==-1)  
    61.             cout<<"Oh,it's impossible~!!"<<endl;  
    62.         else  
    63.             cout<<(1<<free_num)<<endl;  
    64.         Gauss();  
    65.     }  
    66.     return 0;  
    67. }  

     POJ3185  http://poj.org/problem?id=3185


    一维的更简单 随便搞 

    1. #include <iostream>  
    2. #include <cstring>  
    3. #include <cstdio>  
    4. using namespace std;  
    5.   
    6. const int maxn = 21;  
    7.   
    8. int equ,var,free_num,free_x[maxn];  
    9. int a[maxn][maxn],x[maxn],s[maxn];  
    10.   
    11. void init()  
    12. {  
    13.     memset(a,0,sizeof(a));  
    14.     memset(x,0,sizeof(x));  
    15.     var=equ=20;  
    16.     free_num=0;  
    17.     for(int i=0;i<20;i++){  
    18.         a[i][i]=1;  
    19.         if(i!=0) a[i][i-1]=1;  
    20.         if(i!=19) a[i][i+1]=1;  
    21.         if(s[i]) a[i][20]=1;  
    22.     }  
    23. }  
    24.   
    25. int Gauss()  
    26. {  
    27.     int k,col;  
    28.     for(k=0,col=0;k<equ&&col<var;k++,col++){  
    29.         int mx=k;  
    30.         for(int i=k+1;i<equ;i++)  
    31.             if(a[i][col]>a[mx][col]) mx=i;  
    32.         for(int i=col;i<var+1;i++)  
    33.             swap(a[k][i],a[mx][i]);  
    34.         if(!a[k][col]){  
    35.             k--;  
    36.             free_x[free_num++]=col;  
    37.             continue;  
    38.         }  
    39.         for(int i=k+1;i<equ;i++){  
    40.             if(a[i][col]){  
    41.                 for(int j=col;j<var+1;j++)  
    42.                     a[i][j]^=a[k][j];  
    43.             }  
    44.         }  
    45.     }  
    46.     for(int i=k;i<equ;i++)  
    47.         if(a[i][col]) return -1;  
    48.     return var-k;  
    49. }  
    50.   
    51. int calu()  
    52. {  
    53.     int t=Gauss();  
    54.     if(t==-1) return -1;  
    55.     int ans;  
    56.     if(t==0){  
    57.         ans=0;  
    58.         for(int i=var-1;i>=0;i--){  
    59.             x[i]=a[i][var];  
    60.             for(int j=i+1;j<var;j++)  
    61.                 x[i]^=(x[j]&&a[i][j]);  
    62.             ans+=x[i];  
    63.         }  
    64.     }  
    65.     else{  
    66.         ans=10000000;  
    67.         for(int i=0;i<(1<<t);i++){  
    68.             int tmp=0;  
    69.             for(int j=0;j<t;j++){  
    70.                 if(i&(1<<j)){  
    71.                     x[free_x[j]]=1;  
    72.                     tmp++;  
    73.                 }  
    74.                 else  
    75.                     x[free_x[j]]=0;  
    76.             }  
    77.             for(int j=var-t-1,k;j>=0;j--){  
    78.                 for(k=j;k<var;k++)  
    79.                     if(a[j][k]) break;  
    80.                 x[k]=a[j][var];  
    81.                 for(int l=k+1;l<var;l++)  
    82.                     x[k]^=(a[j][l]&&x[l]);  
    83.                 tmp+=x[k];  
    84.             }  
    85.             ans=min(ans,tmp);  
    86.         }  
    87.     }  
    88.     return ans;  
    89. }  
    90. int main()  
    91. {  
    92.     while(~scanf("%d",&s[0])){  
    93.         for(int i=1;i<20;i++)  
    94.             scanf("%d",&s[i]);  
    95.         init();  
    96.         cout<<calu()<<endl;  
    97.     }  
    98.     return 0;  
    99. }  

    POJ 2965 http://poj.org/problem?id=2965

    AX=B  => X=A^(-1)*B  通过逆矩阵来求X,当然这题也能够打表 把A的逆矩阵给打出来 后面来一组数据乘一次 效率非常高

    1. #include <iostream>  
    2. #include <cstring>  
    3. #include <cstdio>  
    4. using namespace std;  
    5.   
    6. int a[16][33];  
    7. int free_x[16],equ,var;  
    8. int c[16][16];  
    9. /*int c[16][16]={ 
    10. 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 
    11. 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 
    12. 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 
    13. 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 
    14. 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 
    15. 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 
    16. 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 
    17. 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 
    18. 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 
    19. 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 
    20. 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 
    21. 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 
    22. 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 
    23. 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 
    24. 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 
    25. 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1 
    26. };*/  
    27. void init()  
    28. {  
    29.     memset(a,0,sizeof(a));  
    30.     int k=0;  
    31.     for(int i=0;i<4;i++){  
    32.         for(int j=0;j<4;j++){  
    33.             k=i*4+j;  
    34.             for(int p=0;p<4;p++){  
    35.                 a[k][i*4+p]=1;  
    36.                 a[k][p*4+j]=1;  
    37.             }  
    38.         }  
    39.     }  
    40.     for(int i=0;i<16;i++) a[i][i+16]=1;  
    41. }  
    42.   
    43.   
    44.   
    45. void gauss()  
    46. {  
    47.     for(int i=0;i<16;i++){  
    48.         int k;  
    49.         for(k=i;k<16;k++)  
    50.             if(a[k][i]) break;  
    51.         for(int j=0;j<32;j++) swap(a[i][j],a[k][j]);  
    52.         for(int j=0;j<16;j++){  
    53.             if(i!=j&&a[j][i]){  
    54.                 for(int k=0;k<32;k++)  
    55.                     a[j][k]=a[j][k]^a[i][k];  
    56.             }  
    57.         }  
    58.     }  
    59.     for(int i=0;i<16;i++)  
    60.         for(int j=0;j<16;j++)  
    61.         c[i][j]=a[i][j+16];  
    62. }  
    63. int main()  
    64. {  
    65.     char mp[10];  
    66.     int b[16];  
    67.     memset(b,0,sizeof(b));  
    68.     for(int i=0;i<4;i++){  
    69.         cin>>mp;  
    70.         for(int j=0;j<4;j++){  
    71.             if(mp[j]=='+')  
    72.                 b[i*4+j]=1;  
    73.         }  
    74.     }  
    75.     init();  
    76.     gauss();  
    77.     /*for(int i=0;i<16;i++){ 
    78.         for(int j=0;j<16;j++) 
    79.             cout<<c[i][j]<<","; 
    80.         cout<<endl; 
    81.     }*/  
    82.     int ans[16];  
    83.     int sum=0;  
    84.     memset(ans,0,sizeof(ans));  
    85.     for(int i=0;i<16;i++){  
    86.         for(int j=0;j<16;j++)  
    87.         ans[i]=ans[i]^(c[i][j]&&b[j]);  
    88.         sum+=ans[i];  
    89.     }  
    90.     cout<<sum<<endl;  
    91.     for(int i=0;i<16;i++){  
    92.         if(ans[i]==1)  
    93.             cout<<i/4+1<<" "<<i%4+1<<endl;  
    94.     }  
    95.     return 0;  
    96. }  

  • 相关阅读:
    PSP
    【探路者】Final发布
    【探路者】final贡献分配
    【探路者】第六周立会报告6(总第39次)
    【探路者】第六周立会报告5(总第38次)
    【探路者】第六周立会报告4(总第37次)
    "Hello World!"团队负责人领跑衫感言
    PSP总结报告
    软件工程第十二次作业——例行报告
    Final阶段中间产物
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7190738.html
Copyright © 2020-2023  润新知