[POJ]POJ1753(dfs)

题意:给出一个4*4的01方阵,每次可以选择一个坐标,使这个坐标以及相邻坐标(如果存在)状态取反,求最少步数使得全0或全1

显然每个坐标最多选一次,枚举最小步数dfs。

#include <cstdio>
#include<iostream>
#include<algorithm>

using namespace std;

typedef long long int LL;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define pll pair <LL, LL>
#define pii pair <int, int>
#define rep(i,x) for(int i=1;i<=x;i++)

const int N = 1e5+7;
const int MX = 1e9+7;
const LL INF = 1e18+9LL;

char a[6][6];

int check(){
	int x=0;
	rep(i,4)
	rep(j,4)if(a[i][j]=='b')x++;
	return x==16||x==0;
}

void make(int x,int y){
	a[x][y]=(a[x][y]=='b'? 'w':'b');
	a[x][y+1]=(a[x][y+1]=='b'? 'w':'b');
	a[x][y-1]=(a[x][y-1]=='b'? 'w':'b');
	a[x+1][y]=(a[x+1][y]=='b'? 'w':'b');
	a[x-1][y]=(a[x-1][y]=='b'? 'w':'b');
} 

int dfs(int s,int x,int y){
	if(!s||x>4)return check();
	if(4*(4-x)+5-y<s)return 0;//剪枝后速度快4倍
	int f;
	if(y<4){
	    f=dfs(s,x,y+1);
	    if(f)return 1;
 	    make(x,y);
	    f=f||dfs(s-1,x,y+1);
	    make(x,y);
	    return f;
	}
	
	else {
		f=dfs(s,x+1,1);
	    if(f)return 1;
	    make(x,y);
	    f=f||dfs(s-1,x+1,1);
	    make(x,y);
	    return f;
	}
} 

int main(){
	rep(i,4)scanf("%s",a[i]+1);
	for(int i=0;i<=16;i++){
		if(dfs(i,1,1)){
			cout<<i;return 0;
		} 
	}
	
	cout<<"Impossible";
	return 0;
}
原文地址:https://www.cnblogs.com/xutianshu/p/10157427.html