http://poj.org/problem?id=3279
在n*N的矩阵上,0代表白色,1代表黑色,每次选取一个点可以其颜色换过来,即白色变成黑色,黑色变成白色,而且其上下左右的点颜色也要交换,求最少交换多少点能把全部换成颜色0
输出所需要换的点,用1表示,如果有多种方案,输出字典序足最小的方案
但是这题的数据里没有字典序的情况,所以没有比较字典序也可以过,我一开始就不知道这个怎么按字典序排
用二进制枚举第一行翻转的所有的情况,然后第一行的翻转确定了再一行行的往下枚举点坑,找出全为0的情况。
第一行的情况确定了,下面的就确定了
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 int dx[5]={1,-1,0,0,0}; 5 int dy[5]={0,0,-1,1,0}; 6 int a[20][20],b[20][20],c[20][20]; 7 int n,m; 8 int sreach(int x) 9 { 10 for (int i=1;i<=m;i++){ 11 if (x&(1<<(i-1))){ 12 c[1][i]=1; 13 for (int j=0;j<5;j++) 14 b[1+dx[j]][i+dy[j]]^=1; 15 } 16 } 17 for (int i=2;i<=n;i++){ 18 for (int j=1;j<=m;j++){ 19 if (b[i-1][j]==1){ 20 c[i][j]=1; 21 for (int k=0;k<5;k++){ 22 b[i+dx[k]][j+dy[k]]^=1; 23 } 24 } 25 } 26 } 27 for (int i=1;i<=m;i++) 28 if (b[n][i]) return 0; 29 return 1; 30 } 31 int main() 32 { 33 int i,j; 34 while (~scanf("%d %d",&n,&m)) 35 { 36 int flag=0; 37 for (i=1;i<=n;i++){ 38 for (j=1;j<=m;j++) 39 scanf("%d",&a[i][j]); 40 } 41 for (i=0;i<(1<<m);i++) 42 { 43 memcpy(b,a,sizeof(a)); 44 memset(c,0,sizeof(c)); 45 if (sreach(i)) 46 { 47 flag=1; 48 break; 49 } 50 } 51 if (!flag) printf("IMPOSSIBLE\n"); 52 else { 53 for (i=1;i<=n;i++){ 54 for (j=1;j<=m;j++){ 55 printf("%d",c[i][j]); 56 if (j!=m) printf(" "); 57 } 58 printf("\n"); 59 } 60 } 61 } 62 return 0; 63 }