您的位置:首页 > 其它

POJ2965-The Pilots Brothers' refrigerator

2011-07-29 02:05 197 查看
转载请注明出处:優YoU [b]http://user.qzone.qq.com/289065406/blog/1299077378[b][/b][/b]
[b][b][b][b][/b][/b][/b][/b]
提示:这题和POJ1753翻转棋的思想是一致的,需要注意的是要求输出翻转过程,因此不能用BFS,必须用DFS(找到目标后,还要过程回溯)
与POJ1753相比,这题还要注意翻棋的方法,若不注意会大大浪费时间导致超时,因为是整行整列翻转,在边界处会出现很多多余操作。代码中详细说明
同样本题有两种方法,Enum和Bit ,下面分别贴出这两种代码

/*代码一:DFS+Enum*/

//Memory Time 
//240K  641MS 

//本题由于要输出每次翻转的棋子,因此不适宜用BFS,应该使用DFS输出完整路径

#include<iostream>
using namespace std;

bool lock[10][10]={false};
bool flag;
int step;
int ri[16],cj[16];

bool isopen(void)
{
	for(int i=3;i<7;i++)
		for(int j=3;j<7;j++)
			if(lock[i][j]!=true)
				return false;
	return true;
}

void flip(int row,int col)               //其实参考POJ1753的翻棋方法也是可以做出来的,但是会超时不通过
{                                        //超时的原因就是翻棋时有太多多余的操作
	lock[row][col]=!lock[row][col];      //POJ1753使用6x6矩形,多余操作只有周围的“一圈”翻棋!
	for(int i=3;i<=6;i++)                //这里使用10x10矩形,多余操作有“三圈”翻棋!
		lock[i][col]=!lock[i][col];      //其实用位运算就可以只使用4x4矩形,大大降低时间复杂度,根本没有多余操作,但是程序会很复杂,不好看
	for(int j=3;j<=6;j++)
		lock[row][j]=!lock[row][j];
	return;
}

void dfs(int row,int col,int deep)
{
	if(deep==step)
	{
		flag=isopen();
	    return;
	}

	if(flag||row==7)return;

	flip(row,col);
	ri[deep]=row;
	cj[deep]=col;

	if(col<6)
		dfs(row,col+1,deep+1);
	else
		dfs(row+1,3,deep+1);

	flip(row,col);
	if(col<6)
		dfs(row,col+1,deep);
	else
	    dfs(row+1,3,deep);
	return;
}

int main(void)
{
	char temp;
	int i,j;
	for(i=3;i<7;i++)
		for(j=3;j<7;j++)
		{
			cin>>temp;
			if(temp=='-')
				lock[i][j]=true;
		}

	for(step=0;step<=16;step++)
	{
		dfs(3,3,0);
		if(flag)break;
	}

	cout<<step<<endl;
	for(i=0;i<step;i++)
		cout<<ri[i]-2<<' '<<cj[i]-2<<endl;
	return 0;
}


=============华丽的分割线=============

/*代码二:DFS+Bit*/

//Memory Time 
//240K   563MS 

//本题由于要输出每次翻转的棋子,因此不适宜用BFS,应该使用DFS输出完整路径

#include<iostream>
using namespace std;

int chess;        //棋盘状态
int step;
bool flag=false;
int ri[16],cj[16];

bool isopen(void)
{
	if(chess==0xFFFF)
		return true;
	else
		return false;
}

void flip(int bit)
{
	chess=chess^(0x1<<bit);  //对翻转位取反
	int row=bit/4;
	int col=bit%4;
	for(int c=0;c<4;c++)
		chess=chess^(0x1<<(row*4+c));  //对全行取反
	for(int r=0;r<4;r++)
		chess=chess^(0x1<<(r*4+col));  //对全列取反
	return;
}

void dfs(int bit,int deep)
{
	if(deep==step)
	{
		flag=isopen();
		return;
	}

	if(flag||bit>15)return;

	int row=ri[deep]=bit/4;
	int col=cj[deep]=bit%4;

	flip(bit);
	if(col<4)
		dfs(bit+1,deep+1);
	else
	    dfs((bit+4)/4*4,deep+1);

	flip(bit);
	if(col<4)
		dfs(bit+1,deep);
	else
		dfs((bit+4)/4*4,deep);
	return;
}

int main(void)
{
	/*Input initial state*/

	char temp;
	int i,j;
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
		{
			cin>>temp;
			if(temp=='-')
				chess=chess^(0x1<<(i*4+j));
		}

	/*DFS*/

	for(step=0;step<=16;step++)
	{
		dfs(0,0);
		if(flag)
			break;
	}

	cout<<step<<endl;
	for(i=0;i<step;i++)
		cout<<ri[i]+1<<' '<<cj[i]+1<<endl;
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: