题意:#字形的图形,问将中间那一块转成相同数字需要的最少步数,输出字典序最小的路径。
分析:跟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;
}