#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"<<endl
using 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;
}
位运算 反转卡片问题
最新推荐文章于 2021-05-22 02:39:52 发布