您的位置:首页 > 其它

1085: [SCOI2005]骑士精神

2014-03-01 07:26 232 查看

1085: [SCOI2005]骑士精神

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 534  Solved: 280

[Submit][Status]


Description

在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空位上。 给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘:
为了体现出骑士精神,他们必须以最少的步数完成任务。




Input

第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位。两组数据之间没有空行。


Output

对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。


Sample Input

2

10110

01*11

10111

01001

00000

01011

110*1

01110

01010

00100


Sample Output

7

-1


HINT


Source

这题数据较小,所以可以考虑搜索
这题的估价函数是比较好写的,对于每个格子,如果他与标准格子不同计数器+1,最后计数器-1一定《=实际代价,鉴于这题状态数多,而且只有15层,所以可以用IDA*
下面贴代码
/**************************************************************
Problem: 1085
User: SKYDEC
Language: C++
Result: Accepted
Time:1436 ms
Memory:804 kb
****************************************************************/

#include<stdio.h>
using namespace std;
struct chess{
long h[6][6];
}stdp;
long dx[10]={0,-1,-1,1,1,-2,-2,2,2};
long dy[10]={0,-2,2,-2,2,-1,1,-1,1};
long f(chess a)
{
long ans=0;
for(long i=1;i<=5;i++)
for(long j=1;j<=5;j++)
if(a.h[i][j]!=stdp.h[i][j])ans++;
ans--;
return ans;
}
bool flag=false;
void swap(long &a,long &b)
{
long t=a;a=b;b=t;
}
void A_star(long x,long y,chess now,long up,long step)
{
if(flag)return;
if(step>up)return;
if(f(now)==-1){flag=true;return;}
if(f(now)+step>up)return;
for(long i=1;i<=8;i++)
if(dx[i]+x>=1&&dx[i]+x<=5&&dy[i]+y>=1&&dy[i]+y<=5)
{
swap(now.h[x][y],now.h[x+dx[i]][y+dy[i]]);
//if(f(now)+step>up)return;
A_star(x+dx[i],y+dy[i],now,up,step+1);
swap(now.h[x][y],now.h[x+dx[i]][y+dy[i]]);
}
}
int main()
{
for(long i=1;i<=5;i++){stdp.h[1][i]=1;stdp.h[5][i]=0;}
stdp.h[2][1]=stdp.h[3][1]=stdp.h[3][2]=stdp.h[4][1]=stdp.h[4][2]=stdp.h[4][3]=stdp.h[4][4]=0;
stdp.h[2][2]=stdp.h[2][3]=stdp.h[2][4]=stdp.h[2][5]=stdp.h[3][4]=stdp.h[3][5]=stdp.h[4][5]=1;stdp.h[3][3]=2;
long test;scanf("%ld\n",&test);char goe;
for(long cao=1;cao<=test;cao++)
{
chess start;long sx,sy;
for(long i=1;i<=5;i++)
{
for(long j=1;j<=5;j++)
{
scanf("%c",&goe);
if(goe!='*')start.h[i][j]=goe-'0';else{start.h[i][j]=2;sx=i;sy=j;}
}
scanf("%c",&goe);
}
flag=false;
if(f(start)==-1)printf("0\n");
else
{
for(long i=1;i<=15;i++)
if(!flag)
{
A_star(sx,sy,start,i,0);
if(flag)printf("%ld\n",i);
}
if(!flag)printf("-1\n");
}
}
//for(;;);
return 0;
}

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