【poj2965 The Pilots Brothers' refrigerator】(基本算法之枚举,同poj1753)

链接:http://poj.org/problem?id=2965

题意:有4*4的矩阵,想要将每个开关的状态变成-,每一次操作定义为:选中一个以及该行该列的所有开关都取反一次,求最少的操作次数,并输出其路径

分析:题目是poj1753的变式,首先必须明确的是操作的顺序对结果是没有影响的,只有4*4的矩阵,暴力dfs一遍2^16的状态数是可以的。dfs深搜要最小路径的话要保存一下临时路径,在不断比较的过程中赋值,最后输出答案。我就是比较菜得将比较得答案初始化为0,然后就一直找不出哪里错了。快哭了。然后对于这个矩阵坐标的话应该是从0开始的下标比较方便,这样就很容易得出s=i*4+j+1,i=s/4,j=s%4;

代码:

#include<cstdio>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;

char g[5][5];
int a[5][5];
int ansx[20],ansy[20];
int tempx[20],tempy[20];
int res;

int judge(void){
	for(int i=0;i<4;i++){
		for(int j=0;j<4;j++){
			if(!a[i][j])return 0;
		}
	}
	return 1;
}

void flip(int s){
	int r=s/4;
	int c=s%4;
	for(int i=0;i<4;i++){
		a[r][i]=!a[r][i];
		a[i][c]=!a[i][c];
	}
	a[r][c]=!a[r][c];
}

void solve(int s,int t){//遍历到s个,翻转了t个
	if(judge()){
		if(t<res){
			res=t;
			for(int i=1;i<=res;i++){
				ansx[i]=tempx[i];
				ansy[i]=tempy[i];
			}
		}
		return ;
	}
	if(s>=16)return ;
	solve(s+1,t);
	flip(s);
	tempx[t+1]=s/4+1;
	tempy[t+1]=s%4+1;
	solve(s+1,t+1);
	flip(s);
	return ;
}

int main(){
	res=inf;
	for(int i=0;i<4;i++){
		gets(g[i]);
		for(int j=0;j<4;j++){
			a[i][j]=(g[i][j]=='-'?1:0);
		}
	}
	solve(0,0);
	printf("%d\n",res);
	for(int i=1;i<=res;i++){
		printf("%d %d\n",ansx[i],ansy[i]);
	}
}

猜你喜欢

转载自blog.csdn.net/running_acmer/article/details/80874669