poj-3279 Fliptile

来源:互联网 发布:淘宝双色球 编辑:程序博客网 时间:2024/05/08 03:12
思路:首先二进制枚举第一行的情况,然后从上往下依次即可。。


我的实现思路想麻烦了。。。。。具体是用一个op数组记录反转的次数。然后再%2做的,这样实现过程中写法要注意很多东西(我就是WR了好多次)


自己的代码:

int op[20][20];int a[20][20];int m[20][20];int best[20][20];int main(){    int M,N,res=INF;    scanf("%d%d",&M,&N);    for(int i=1;i<=M;i++)    for(int j=1;j<=N;j++) scanf("%d",&a[i][j]);    clr(best);    for(int i=0;i<(1<<N);i++)    {        clr(op);        clr(m);        int ret=0;        for(int j=0;j<N;j++)        {            if((i>>j)&1)            {                op[1][j+1]++;                op[1][j]++;                op[1][j+2]++;                op[2][j+1]++;                m[1][j+1]=1;                ret++;            }        }        for(int k=2;k<=M;k++)        {            for(int p=1;p<=N;p++)            if((a[k-1][p]+op[k-1][p])%2==1)            {                m[k][p]=1;                op[k][p]++;                op[k][p+1]++;                op[k][p-1]++;                op[k+1][p]++;                ret++;            }        }        int flag=0;        for(int k=1;k<=N;k++)        {            if((a[M][k]+op[M][k])%2==1)            {                flag=1;                break;            }        }        if(flag) continue;        if(res>ret)        {            res=ret;            memcpy(best,m,sizeof(m));        }    }    if(res==INF) printf("IMPOSSIBLE\n");    else    {        for(int i=1;i<=M;i++)        {            for(int j=1;j<=N-1;j++) printf("%d ",best[i][j]);            printf("%d\n",best[i][N]);        }    }    return 0;}

比较简单的实现方式。加个方向。。。。
参考博客点击打开链接

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int inf = 0x3f3f3f3f;int dxy[5][2] = { {0, 1}, {1, 0}, {0, 0}, {-1, 0}, {0, -1} };int m, n, a[20][20], ans[20][20], opt[20][20];int judge(int x, int y){    //返回(i, j)的正反情况    int ret = a[x][y];    for(int i=0; i<5; i++){        int xx = dxy[i][0] + x;        int yy = dxy[i][1] + y;        if(xx >= 0 && xx < m && yy >= 0 && yy < n)            ret += opt[xx][yy]; //跟我正好相反,直接用不方向的来相加。。。。    }    return ret % 2;}int main(){    scanf("%d%d", &m, &n);    int ret = inf;    for(int i=0; i<m; i++)        for(int j=0; j<n; j++)            scanf("%d", &a[i][j]);    for(int i=0; i<(1 << n); i++){   //二进制枚举第一行        memset(opt, 0, sizeof(opt));        int res = 0;        for(int j=0; j<n; j++){            opt[0][n - j - 1] = (i >> j) & 1; //这个从左到右,从右到左,无所谓的            res += opt[0][n - j - 1];        }        for(int j=1; j<m; j++)            for(int k=0; k<n; k++)                if(judge(j - 1, k)) {                    opt[j][k] = 1;                    res++;                }        bool flag = true;        for(int j=0; j<n; j++) if(judge(m - 1, j)) {            flag = false;            break;        }        if(flag && res < ret){            ret = res;            memcpy(ans, opt, sizeof(opt));        }    }    if(ret == inf) puts("IMPOSSIBLE");    else {        for(int i=0; i<m; i++)            for(int j=0; j<n; j++) printf("%d%c", ans[i][j], j == n - 1 ? '\n' : ' ');    }    return 0;}


0 0
原创粉丝点击