poj1753Flip Game<高斯消元>
链接 http://poj.org/problem?id=1753
View Code
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <algorithm> 5 using namespace std; 6 const int N=16; 7 int d[20][20]; 8 int slove( int n ) //枚举自由解 求最小值 9 { 10 int x[20], temp, ans=100, m[4], t, p, k; 11 for( t=1; t<=16; ++t ){ 12 memset( x, 0, sizeof x ); 13 temp=0; 14 for( p=0; p<4; ++p ){ 15 m[p]=(t&( 1<<p )); 16 if( m[p] ){ 17 x[13+p]=1; 18 } 19 } 20 for( p=N; p>0; --p ){ 21 for( k=N; k>0; --k ){ 22 if( p!=k ) 23 x[p] ^= (x[k]*d[p][k]); 24 } 25 x[p] ^= d[p][n]; 26 if (x[p]) { 27 ++temp; 28 } 29 } 30 ans=min( ans, temp ); 31 } 32 return ans; 33 } 34 void Gauss( ) 35 { 36 int i=1, j, k, p, t; 37 38 for( j=1; j<=N; ++i,++j ){ 39 for( p=i; p<=N; p++ ){ 40 if(d[p][j])break; 41 } 42 if( p==N+1 ){--i;continue;} 43 if( p!=i ){ 44 for( k=j; k<=N+2; ++k ){ 45 t=d[i][k]; 46 d[i][k]=d[p][k]; 47 d[p][k]=t; 48 } 49 } 50 for( k=i+1; k<=N; ++k ){ 51 if( d[k][j] ){ 52 for( t=j; t<=N+2; ++t ){ 53 d[k][t]^=d[i][t]; 54 } 55 } 56 } 57 58 } 59 int flag1=0, flag2=0, ans, ans1, ans2; 60 for( int p=i; p<=N; ++p ){ 61 if( d[p][N+1]&& (!d[p][N+2]) )flag1=1; 62 if( (!d[p][N+2])&& d[p][N+2] )flag2=1; 63 if( d[p][N+1]&& d[p][N+2] ) { 64 puts( "Impossible" ); 65 return; 66 } 67 } 68 if( ! flag1 ){ 69 ans1=slove( N+1 ); 70 } 71 if( !flag2 ){ 72 ans2=slove( N+2 ); 73 } 74 if( !flag1 && ! flag2 ){ 75 ans=min( ans1, ans2 ); 76 printf( "%d\n", ans ); 77 return; 78 } 79 if( (!flag1) && flag2 ){ 80 printf( "%d\n", ans1 ); 81 return; 82 } 83 if( flag1 && (!flag2) ){ 84 printf( "%d\n", ans2 ); 85 return; 86 } 87 } 88 int main( ) 89 { 90 char s[4][4]; 91 while( scanf( "%s", s[0])!= EOF ){ 92 for(int i=1; i<4; ++ i ) 93 scanf( "%s", s[i] ); 94 memset( d, 0, sizeof d ); 95 for( int i=1; i<=16; ++ i ) 96 d[i][i]=1; 97 for( int i=0; i<4;++ i ){ 98 for(int j=0; j<4; ++ j){ 99 if( s[i][j]=='b')d[i*4+j+1][N+1]=1; 100 if( s[i][j]=='w')d[i*4+j+1][N+2]=1; 101 if( j>0 )d[4*i+j][4*i+1+j]=1; 102 if( i>0 )d[4*(i-1)+j+1][4*i+1+j]=1; 103 if( j<3 )d[4*i+j+2][4*i+1+j]=1; 104 if( i<3 )d[4*(i+1)+j+1][4*i+1+j]=1; 105 } 106 } 107 108 Gauss( ); 109 } 110 return 0; 111 }