[kuangbin带你飞]专题一 简单搜索(未完待更......)

POJ 3279 Fliptile

题意:

给定一m*n的01矩阵,每翻动一个格子,它上下左右四个格子也会翻面(0变1,1变0),问最少翻动几次,得全0矩阵。如果最小操作数对应多种操作方案 ,输出字典序最小的方案。如果不能得全0矩阵,输出“IMPOSSIBLE”。

思路: 

枚举第一行的操作,然后根据每种操做后的第一行的状态,往下递推后面行的操作(每行的操作由前一行的状态决定),最后判断最后一行是不是全0。

代码:

#include
#include
#include
using namespace std;
const int N=20;
int n,m;

bool a[N][N],b[N][N],vis[N][N],ans[N][N];

void flip(int x,int y){
	a[x][y]^=1,a[x-1][y]^=1,a[x+1][y]^=1,a[x][y-1]^=1,a[x][y+1]^=1;
}

bool check(){
	for(int j=1;j<=n;++j){
		if(a[m][j]) return false;
	}
	return true;
}

int main(){	
    cin>>m>>n;//m行n列
	for(int i=1;i<=m;++i){
		for(int j=1;j<=n;++j){
			cin>>a[i][j];
		}
	}

	int op=1<>j&1){
				flip(1,j+1);//啊我傻缺了!做题专心点好吗。。。= =
				vis[1][j+1]=1;
				++cnt;
			}
		}

		//由第一行状态,递推完成剩下的操作
		for(int k=2;k<=m;++k){ //啊第m行也是要操作的 我好蠢。
			for(int j=1;j<=n;++j){
				if(a[k-1][j]){
					flip(k,j);
					vis[k][j]=1;
					++cnt;
				}
			}
		}
		
		//判断最后一行状态
		if(check()){
			flag=1;
			if(cnta[i][j]) f=0;
					}
				}
			}

		}

		memcpy(a,b,sizeof b);
		memset(vis,0,sizeof vis);
	}

	if(flag){
		for(int i=1;i<=m;++i){
			for(int j=1;j<=n;++j){
				if(j!=1) cout<<" ";
				cout<

PS:同类型题目

费解的开关(递推)

翻硬币(递推)

你可能感兴趣的:(搜索)