hdu1667 The Rotation Game(IDA*)

题意:#字形的图形,问将中间那一块转成相同数字需要的最少步数,输出字典序最小的路径。

分析:跟hdu2234的无题I比,相对简单一点。其实也只是估价函数好理解一点,其他都差不多,还是迭代深搜+A*,也就是IDA*。

估价函数h()=8-max(在要求的八个位置中,1,2,3,的个数);

很好理解,因为没转动一步,最多只能将一个位置改为正确的。所以当前状态下,剩余的最少步数=8-max(在要求的八个位置中,1,2,3,的个数);

#include<iostream>
#include<algorithm>
using namespace std;
int map[8][8],step;
char road[100];
int hash1[8]={3,5,3,5,5,3,5,3};
void TurnCOL(int c,int flag)//转动列,c表示所在列,flag表示向上还是向下,1表示向上
{
	int t;
	if(flag)
	{
		t=map[1][c];
		for(int i=2;i<=7;i++)
			map[i-1][c]=map[i][c];
		map[7][c]=t;
	}
	else {
		t=map[7][c];
		for(int i=6;i>=1;i--)
			map[i+1][c]=map[i][c];
		map[1][c]=t;
	}
}
void TurnROW(int r,int flag)//转动行,r表示所在行,flag表示向右还是向左,1表示向右
{
	int t;
	if(flag)
	{
		t=map[r][7];
		for(int i=6;i>=1;i--)
			map[r][i+1]=map[r][i];
		map[r][1]=t;
	}
	else {
		t=map[r][1];
		for(int i=2;i<=7;i++)
			map[r][i-1]=map[r][i];
		map[r][7]=t;
	}
}
int check()
{
	int num[4]={0};
	for(int i=3;i<=5;i++)
	{
		num[map[3][i]]++;
		num[map[5][i]]++;
	}
	num[map[4][3]]++;
	num[map[4][5]]++;
	int t=max(num[1],max(num[2],num[3]));
	return t;
}
bool dfs(int cnt)
{
	int t=check();
	if(t==8 && cnt==step)
		return true;
	if(cnt+(8-t)>step)
		return false;
	char c;
	for(int i=0;i<8;i++)
	{
		c=i+'A';
		road[cnt]=c;
		if(c=='A'|| c=='B')
		{
			TurnCOL(hash1[i],1);
			if(dfs(cnt+1)) return true;
			TurnCOL(hash1[i],0);
		}
		else if(c=='F'||c=='E')
		{
			TurnCOL(hash1[i],0);
			if(dfs(cnt+1))return true;
			TurnCOL(hash1[i],1);
		}
		else if(c=='C'||c=='D')
		{
			TurnROW(hash1[i],1);
			if(dfs(cnt+1)) return true;
			TurnROW(hash1[i],0);
		}
		else {
			TurnROW(hash1[i],0);
			if(dfs(cnt+1)) return true;
			TurnROW(hash1[i],1);
		}
	}
	return false;
}
int main()
{
	int a,b;
	while(scanf("%d",&a)==1 && a)
	{
		scanf("%d",&b);
		memset(map,0,sizeof(map));
		map[1][3]=a;
		map[1][5]=b;
		for(int i=2;i<=7;i++)
		{
			if(i==3|| i==5)
			{
				for(int j=1;j<=7;j++)
					scanf("%d",&map[i][j]);
				continue;
			}
			scanf("%d %d",&map[i][3],&map[i][5]);
		}
		if(check()==8)
		{
			puts("No moves needed");
			printf("%d\n",map[3][3]);//忘记输出这一句,WA了一次
			continue;
		}
		step=1;
		while(true)
		{
			if(dfs(0))
				break;
			step++;
		}
		road[step]='\0';
		puts(road);
		printf("%d\n",map[3][3]);
	}
	return 0;
}

 

posted @ 2011-12-08 20:43  枕边梦  阅读(325)  评论(0编辑  收藏  举报