位运算 反转卡片问题

来源:互联网 发布:苏州买茶叶知乎 编辑:程序博客网 时间:2024/06/05 00:30
#pragma comment(linker, "/STACK:1024000000,1024000000")#include <algorithm>#include <bitset>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <map>#include <queue>#include <set>#include <stack>#include <string>#include <cctype>#include <fstream>#define INF 0x3f3f3f3f#define TEST cout<<"stop here"<<endlusing namespace std;typedef long long ll;const ll mod = 1e9 + 7;int m,n;int raw[20][20],tmp[20][20],ans[20][20];//原始数据/临时数据/最终答案int maxx = INF;void DFS(){//暴力枚举    int cur[20][20];    memcpy(cur,raw,sizeof(raw));    for(int j=1;j<=m;j++){//初始化,枚举第一行        if(tmp[1][j]){            cur[1][j] ^= 1;            if(n>=2)                cur[2][j] ^= 1;            if(j>1){                cur[1][j-1] ^= 1;              }            if(j<m){                cur[1][j+1] ^= 1;            }        }    }    for(int i=2;i<=n;i++){//依据第一行来推算下面的剩余行        for(int j=1;j<=m;j++){            if(cur[i-1][j]){                tmp[i][j] = 1;               // cur[i-1][j] = 0;                cur[i][j] ^= 1;                if(n>i){                    cur[i+1][j] ^= 1;                }                if(j>1){                    cur[i][j-1] ^= 1;                  }                if(j<m){                    cur[i][j+1] ^= 1;                }            }        }    }    bool flag = true;    for(int j=1;j<=m;j++){        if(cur[n][j]){            flag = false;            break;        }    }    if(flag){        int cnt = 0;        for(int i=1;i<=n;i++){            for(int j=1;j<=m;j++){                if(tmp[i][j])                    cnt++;            }        }        if(cnt<maxx){           memcpy(ans,tmp,sizeof(tmp));           maxx = cnt;        }        else if(cnt == maxx){            bool ok = true;            for(int i=1;i<=n;i++){                for(int j=1;j<=m;j++){                    if(ans[i][j] > tmp[i][j]){                        break;                    }                    else if(ans[i][j] < tmp[i][j]){                        ok = false;                        break;                    }                }            }            if(ok){                memcpy(ans,tmp,sizeof(tmp));            }        }    }}int main(){    std::ios::sync_with_stdio(false);    std::cin.tie(0);    while(cin>>n>>m){        for(int i=1;i<=n;i++){            for(int j=1;j<=m;j++){                cin>>raw[i][j];            }        }        maxx = INF;        for(int i=0;i<(1<<m);i++){//枚举子集的操作            memset(tmp,0,sizeof(tmp));            for(int j=0;j<m;j++){                if(i&(1<<j)){                    tmp[1][j+1] = 1;                }                else{                    tmp[1][j+1] = 0;                }            }            DFS();        }        if(maxx == INF){            printf("IMPOSSIBLE\n");        }        else{            for(int i=1;i<=n;i++){                for(int j=1;j<=m;j++){                    cout<< ans[i][j]<< ((j!=m)?" ":"\n");                }            }        }    }    return 0;}
原创粉丝点击