题意:有20个数字,0或1。如果改变一个数的状态,它左右两边的两个数的状态也会变反。问从目标状态到全0,至少需要多少次操作。
分析:
和上一题差不多,但是比上一题还简单,不多说了,但是在做题的时候犯了一个非常二的错误。。看图吧。
先输入了a[0]又,初始了a[]【】数组
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <algorithm> 7 #define LL __int64 8 const int maxn = 400+10; 9 const int INF = 1<<28; 10 using namespace std; 11 int equ, var, fn; 12 int a[maxn][maxn], x[maxn]; 13 int free_x[maxn]; 14 int gcd(int a, int b) 15 { 16 return b==0?a:gcd(b, a%b); 17 } 18 int lcm(int a, int b) 19 { 20 return a*b/gcd(a, b); 21 } 22 int Gauss() 23 { 24 int x_mo; 25 x_mo = 2; 26 int i, j, k, max_r, col; 27 int ta, tb, LCM, fx_num = 0; 28 col = 0; 29 30 for(k = 0; k<equ && col<var; k++, col++) 31 { 32 max_r = k; 33 for(i = k+1; i < equ; i++) 34 if(abs(a[i][col])>abs(a[max_r][col])) 35 max_r = i; 36 37 if(max_r != k) 38 for(j = k; j < var+1; j++) 39 swap(a[k][j], a[max_r][j]); 40 41 if(a[k][col]==0) 42 { 43 free_x[fx_num++] = col; //求自由变元所在的列 44 k--; 45 continue; 46 } 47 for(i = k+1; i < equ; i++) 48 { 49 if(a[i][col] != 0) 50 { 51 LCM = lcm(abs(a[i][col]), abs(a[k][col])); 52 ta = LCM/abs(a[i][col]); 53 tb= LCM/abs(a[k][col]); 54 if(a[i][col]*a[k][col] < 0) tb = -tb; 55 56 for(j = col; j < var+1; j++) 57 a[i][j] = ((a[i][j]*ta - a[k][j]*tb)%x_mo+x_mo)%x_mo; 58 } 59 } 60 } 61 for(i = k; i < equ; i++) 62 if(a[i][col] != 0) 63 return INF; 64 65 int stat=1<<(var-k); 66 int res=INF; 67 for(i=0; i<stat; i++) 68 { 69 int cnt=0; 70 int index=i; 71 for(j=0; j<var-k; j++) 72 { 73 x[free_x[j]]=(index&1); 74 if(x[free_x[j]]) cnt++; 75 index>>=1; 76 } 77 for(j=k-1; j>=0; j--) 78 { 79 int tmp=a[j][var]; 80 for(int l=j+1; l<var; l++) 81 if(a[j][l]) tmp^=x[l]; 82 x[j]=tmp; 83 if(x[j])cnt++; 84 } 85 if(cnt<res)res=cnt; 86 } 87 return res; 88 } 89 90 void init() 91 { 92 int i; 93 memset(a, 0, sizeof(a)); 94 memset(x, 0, sizeof(x)); 95 for(i = 0; i < 20; i++) 96 { 97 a[i][i] = 1; 98 if(i+1<20) 99 a[i+1][i] = 1; 100 if(i-1>=0) 101 a[i-1][i] = 1; 102 } 103 } 104 int main() 105 { 106 int i; 107 equ = 20; 108 var = 20; 109 init(); 110 for(i = 0; i < 20; i++) 111 scanf("%d", &a[i][20]); 112 fn = Gauss(); 113 printf("%d ", fn); 114 return 0; 115 }