标签:return alt stream tab mil osi pre str script
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 9612 | Accepted: 6246 |
Description
Input
Output
Sample Input
2 0 1 1 0 1 0 1 0 0 1 1 1 0 0 1 0 0 1 1 0 0 1 0 1 0 1 1 1 0 0 0 0 1 0 1 0 1 0 1 0 1 1 0 0 1 0 1 1 1 0 1 1 0 0 0 1 0 1 0 0
Sample Output
PUZZLE #1 1 0 1 0 0 1 1 1 0 1 0 1 0 0 1 0 1 1 1 0 0 1 0 0 0 1 0 0 0 0 PUZZLE #2 1 0 0 1 1 1 1 1 0 0 0 0 0 0 0 1 0 0 1 1 0 1 0 1 1 0 1 1 0 1
Source
题意:
有5行6列共30个开关,每按动一个开关,该开关及其上下左右共5个开关的状态都会改变,初始给你这30个开关的状态求按动那些开关能够使这些开关的状态都是0.
思路:因为每盏灯,如果操作两次就相当于没有操作,所以相当于(操作次数)%2,即异或操作。
考虑一个2*3的图,最后需要的状态是 :,如果初始状态为:。对这两个矩阵的每个数字做异或操作可以得到线性方程组每个方程的答案。
总共6盏灯,0-5。那么可以列出6个方程。
对于第0盏灯,会影响到它的是第0, 1, 3盏灯,因此可以列出方程1*x0 + 1*x1 + 0*x2 + 1*x3 + 0*x4 + 0*x5= 0。
对于第1盏灯,会影响到它的是第0, 1, 2,4盏灯,因此可以列出方程1*x0 + 1*x1 + 1*x2 + 0*x3 + 1*x4 + 0*x5 = 1。
对于第2盏灯,会影响到它的是第1, 2, 5盏灯,因此可以列出方程0*x0 + 1*x1 + 1*x2 + 0*x3 + 0*x4 + 1*x5 = 0。
.....
所以最后可以列出增广矩阵:
然后用高斯消元求这个矩阵的解就可以了。
30个变量30个方程组
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 using namespace std; 6 const int MAX=40; 7 int a[MAX][MAX]; //增广矩阵 8 int x[MAX]; //解集 9 int equ,var; //行数和列数 10 void init() 11 { 12 equ=30;var=30; 13 memset(a,0,sizeof(a)); 14 for(int i=0;i<5;i++) //t点和上下左右都改变 15 for(int j=0;j<6;j++) 16 { 17 int t=6*i+j; 18 a[t][t]=1; 19 if(i>0) a[6*(i-1)+j][t]=1; 20 if(i<4) a[6*(i+1)+j][t]=1; 21 if(j>0) a[t-1][t]=1; 22 if(j<5) a[t+1][t]=1; 23 } 24 } 25 void gaos() 26 { 27 int maxr; 28 for(int k=0,col=0;k<equ&&col<var;k++,col++) 29 { 30 maxr=k; /****变为行阶梯形矩阵***/ 31 for(int i=k+1;i<equ;i++) 32 if(abs(a[i][col])>abs(a[maxr][col])) 33 maxr=i; 34 if(maxr!=k) 35 { 36 for(int i=col;i<var+1;i++) 37 swap(a[maxr][i],a[k][i]); 38 } 39 if(a[k][col]==0) //第k行后的第col列全部是0了,换下一列 40 { 41 k--; 42 continue; 43 } 44 for(int i=k+1;i<equ;i++) //第k行减去第i行的值赋给第i行,变为行阶梯型矩阵,由于都是01型矩阵,不用找lcm直接减就行 45 { 46 if(a[i][col]!=0) 47 { 48 for(int j=col;j<var+1;j++) 49 a[i][j]^=a[k][j]; 50 } 51 } 52 for(int i=var-1;i>=0;i--) //算出解集 53 { 54 x[i]=a[i][var]; 55 for(int j=i+1;j<var;j++) //该行第var列是1说明该行有且只有一个x取1,若为0说明没有取1的x. 56 x[i]^=(a[i][j]&x[j]); 57 } 58 } 59 } 60 int main() 61 { 62 int t,ca=0; 63 scanf("%d",&t); 64 while(t--) 65 { 66 ca++; 67 init(); 68 for(int i=0;i<30;i++) 69 scanf("%d",&a[i][30]); 70 gaos(); 71 printf("PUZZLE #%d",ca); 72 for(int i=0;i<30;i++) 73 { 74 if(i%6==0) printf("\n%d",x[i]); 75 else printf(" %d",x[i]); 76 } 77 printf("\n"); 78 } 79 return 0; 80 }
标签:return alt stream tab mil osi pre str script
原文地址:http://www.cnblogs.com/--ZHIYUAN/p/6136893.html