您的位置:首页 > 其它

UVA-1343 The Rotation Game (IDA*)

2015-09-24 00:19 295 查看
题目大意:数字1,2,3都有八个,求出最少的旋转次数使得图形中间八个数相同。旋转规则:对于每一长行或每一长列,每次旋转就是将数据向头的位置移动一位,头上的数放置到尾部。若次数相同,则找出字典序最小旋转次序。

题目分析:IDA*,若当前在第cur层,中间八个数中1,2,3的个数分别为a,b,c。则d=8-max(a,b,c)便是达到目标还需要的理想次数,若cur+d>maxd,则剪枝。《入门经典》上提供了一种BFS的思路,分别以1,2,3为目标广搜3次,不过自己的码力还是太弱,并没有用那种方法AC。。。!!!

代码如下:

# include<iostream>
# include<cstdio>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std;

int a[24],d[8][7]={
{0,2,6,11,15,20,22},
{1,3,8,12,17,21,23},
{10,9,8,7,6,5,4},
{19,18,17,16,15,14,13},
{23,21,17,12,8,3,1},
{22,20,15,11,6,2,0},
{13,14,15,16,17,18,19},
{4,5,6,7,8,9,10},
};
int g[8]={6,7,8,11,12,15,16,17};
int ans;
string ansp;

bool dfs(int cur,int maxd,string path)
{
if(cur==maxd){
int ok=1;
for(int i=1;i<8;++i)
if(a[g[i]]!=a[g[i-1]]){
ok=0;
break;
}
if(!ok)
return false;
ans=a[g[0]],ansp=path;
return true;
}
int b[3]={0,0,0};
for(int i=0;i<8;++i)
++b[a[g[i]]-1];
int dd=8-max(max(b[0],b[1]),b[2]);
if(cur+dd>maxd)
return false;
for(int i=0;i<8;++i){
int v=a[d[i][0]];
for(int j=0;j<6;++j)
a[d[i][j]]=a[d[i][j+1]];
a[d[i][6]]=v;
if(dfs(cur+1,maxd,path+char(i+'A')))
return true;
v=a[d[i][6]];
for(int j=6;j>0;--j)
a[d[i][j]]=a[d[i][j-1]];
a[d[i][0]]=v;
}
return false;
}

int main()
{
while(scanf("%d",&a[0])&&a[0])
{
for(int i=1;i<24;++i)
scanf("%d",a+i);

ans=-1;
for(int maxd=0;;++maxd){
if(dfs(0,maxd,"")){
if(maxd==0)
printf("No moves needed\n");
else
cout<<ansp<<endl;
printf("%d\n",ans);
break;
}
}
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: