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 }

 

posted on 2015-12-03 12:40  蜘蛛侦探  阅读(259)  评论(0编辑  收藏  举报