题解 UVA1343 【旋转游戏 The Rotation Game】
分析
显然,这题需要深搜。
我们先记 A 到 H 的操作分别为 到 ,深搜的同时,全局建一个 vector 型变量 记录答案,对于当前的状态,我们有 种移动方式,不断往下搜即可。
一个剪枝
我们的 种存储了上一次的操作,显然,如果执行上一次的逆操作,那么状态就会回到上一次移动前的状态,造成等效冗余,不能满足最小次数的要求,所以每次不应执行上一次的逆操作。
每个操作的逆操作对应如下:
1-6 2-5 3-8 4-7
5-2 6-1 7-4 8-3
一个优化
显然,如果这题仅仅是这样就不是蓝题了, 我们还需要更多的优化。
可以发现,在每个状态下,如果中间的 个格子出现次数最多的数字出现了 次,而每次修改只能增加或减少不超过 个出现次数最多的数字,那么想要凑满 个至少要 次,我们可以使用启发式搜索IDA* ,设估价函数 表示当前状态下最少需要的操作次数,从 开始从小到大限制搜索的次数,设当前操作次数为 ,限制步数为 ,若 ,则返回不可行。
代码
#include<bits/stdc++.h>
#define mec(a,b) memcpy(a,b,sizeof(a));
using namespace std;
const int N=15;
int a[N][N],step,num[4],dui[9]={0,6,5,8,7,2,1,4,3};
vector<int>ans;
int g()//估价函数
{
num[1]=num[2]=num[3]=0;
for(int i=3;i<6;i++)
for(int j=3;j<6;j++)
{
if(i!=4||j!=4)
num[a[i][j]]++;//统计出现最多的数的次数
}
return 8-max(num[1],max(num[2],num[3]));
}
void move(int op)//移动
{
switch(op)
{
case 1:for(int i=1;i<8;i++)a[i-1][3]=a[i][3];a[7][3]=a[0][3];break;
case 2:for(int i=1;i<8;i++)a[i-1][5]=a[i][5];a[7][5]=a[0][5];break;
case 3:for(int i=7;i;i--)a[3][i+1]=a[3][i];a[3][1]=a[3][8];break;
case 4:for(int i=7;i;i--)a[5][i+1]=a[5][i];a[5][1]=a[5][8];break;
case 5:for(int i=7;i;i--)a[i+1][5]=a[i][5];a[1][5]=a[8][5];break;
case 6:for(int i=7;i;i--)a[i+1][3]=a[i][3];a[1][3]=a[8][3];break;
case 7:for(int i=1;i<8;i++)a[5][i-1]=a[5][i];a[5][7]=a[5][0];break;
case 8:for(int i=1;i<8;i++)a[3][i-1]=a[3][i];a[3][7]=a[3][0];break;
}
}
bool dfs(int now)
{
int gu=g();
if(!gu)//以成功就返回1
return 1;
if(now+gu>step)//超过限制返回0
return 0;
int b[N][N];
mec(b,a);//复制状态
for(int i=1;i<9;i++)
{
if(ans.size()&&ans.back()==dui[i])//不是第一次操作且是逆操作就不执行这个操作
continue;
move(i);
ans.push_back(i);
if(dfs(now+1))
return 1;
ans.pop_back();
mec(a,b);//改变状态
}
return 0;
}
int main()
{
while(cin>>a[1][3]&&a[1][3])
{
ans.clear();
step=0;
cin>>a[1][5]>>a[2][3]>>a[2][5];
for(int i=1;i<=7;i++)
cin>>a[3][i];
cin>>a[4][3]>>a[4][5];
for(int i=1;i<=7;i++)
cin>>a[5][i];
cin>>a[6][3]>>a[6][5]>>a[7][3]>>a[7][5];
while(!dfs(0))
step++;
if(step)
{
for(int i=0;i<ans.size();i++)
putchar(ans[i]+'A'-1);
printf("\n");
}
else printf("No moves needed\n");
printf("%d\n",a[3][3]);
}
return 0;
}

浙公网安备 33010602011771号