POJ

来源:互联网 发布:simcms二手车源码 编辑:程序博客网 时间:2024/05/21 05:37
Farmer John knows that an intellectually satisfied cow is a happy cow who will give more milk. He has arranged a brainy activity for cows in which they manipulate an M × N grid (1 ≤ M ≤ 15; 1 ≤ N ≤ 15) of square tiles, each of which is colored black on one side and white on the other side.

As one would guess, when a single white tile is flipped, it changes to black; when a single black tile is flipped, it changes to white. The cows are rewarded when they flip the tiles so that each tile has the white side face up. However, the cows have rather large hooves and when they try to flip a certain tile, they also flip all the adjacent tiles (tiles that share a full edge with the flipped tile). Since the flips are tiring, the cows want to minimize the number of flips they have to make.

Help the cows determine the minimum number of flips required, and the locations to flip to achieve that minimum. If there are multiple ways to achieve the task with the minimum amount of flips, return the one with the least lexicographical ordering in the output when considered as a string. If the task is impossible, print one line with the word "IMPOSSIBLE".

Input
Line 1: Two space-separated integers: M and N
Lines 2.. M+1: Line i+1 describes the colors (left to right) of row i of the grid with N space-separated integers which are 1 for black and 0 for white
Output

Lines 1.. M: Each line contains N space-separated integers, each specifying how many times to flip that particular location.


题意:在一个只有0,1的矩阵中,改变一个数,与它相邻的数也会随之改变,求最小的改变次数,如果有很多个,那么求字典序最小的那个。

思路:仔细想一下就会发现只要第一排的情况确定了,那么后面的情况也随之确定(因为上一排的情况确定,那么只有下一排才能把上一排的1变成0,一排确定一排),如果最后一排不是全0,就不能成功,否则就行。因为要求是字典序最小,只需每排从小到大算就好了。

注意  ;这里用到了几个二进制数的方法,因为数全是0,1,所以第一排可以看成一个二进制数,i:0->1<<m,枚举了所有第一排的情况,再 j:0->m, 

i & ( 1 << j ) 表示这种情况第j个数是否是1,是的话就f[0][j]标记为1,对了,f数组表示的是每种第一排枚举的中间答案,ans数组表示最后的答案。


代码:

#include <cstdio>#include <cmath>#include <iostream>#include <cstring>#include <algorithm>#include <queue>#include <stack>#include <vector>#include <map>#include <numeric>#include <set>#include <string>#include <cctype>#include <sstream>#define INF 0x3f3f3f3f#define lson l, m, rt<<1#define rson m+1, r, rt<<1|1typedef long long LL;using namespace std;const int maxn = 20 + 5;const int mod = 1e8 + 7;//0->白色,1->黑色int n,m;int a[maxn][maxn],f[maxn][maxn],ans[maxn][maxn];int to[4][2]={0,1,0,-1,1,0,-1,0};int ok(int x,int y){    int c=f[x][y];    for (int i=0;i<4;i++){        int dx=x+to[i][0];        int dy=y+to[i][1];        if (dx<0||dx>=n||dy<0||dy>=m) continue;        c+=f[dx][dy];    }    c+=a[x][y];    return c%2;}int calc(){    for (int i=1;i<n;i++){        for (int j=0;j<m;j++){            if (ok(i-1,j)) f[i][j]=1;        }    }    for (int i=0;i<m;i++){        if (ok(n-1,i)) return -1;    }    int cnt=0;    for (int i=0;i<n;i++){        for (int j=0;j<m;j++){            cnt+=f[i][j];        }    }    return cnt;}int main() {    //freopen ("in.txt", "r", stdin);    while (~scanf ("%d%d",&n,&m)){        int Ans=INF;        for (int i=0;i<n;i++){            for (int j=0;j<m;j++){                scanf ("%d",&a[i][j]);            }        }        for (int i=0;i<(1<<m);i++){            memset (f,0,sizeof(f));            for (int j=0;j<m;j++){                if (i&(1<<j)) f[0][j]=1;            }            int num=calc();            if (num<Ans&&num!=-1){                Ans=num;                memcpy(ans,f,sizeof(f));            }        }        if (Ans==INF||Ans==-1){            printf ("IMPOSSIBLE\n");        }        else {            for (int i=0;i<n;i++){                for (int j=0;j<m;j++){                    printf ("%d%c",ans[i][j],j+1==m? '\n':' ');                }            }        }    }    return 0;}


原创粉丝点击