首页 > 代码库 > 【bzoj1085】[SCOI2005]骑士精神

【bzoj1085】[SCOI2005]骑士精神

1085: [SCOI2005]骑士精神

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1757  Solved: 961
[Submit][Status][Discuss]

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
 
 
【题解】
A*寻路法。
设计一个估价函数h=s+v,如果满足h<k就往下搜,否则不搜,这样就能过了。
 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cmath> 5 #include<ctime> 6 #include<cstring> 7 #include<algorithm> 8 using namespace std; 9 const int ans[5][5]={{1,1,1,1,1},{0,1,1,1,1},{0,0,2,1,1},{0,0,0,0,1},{0,0,0,0,0}};10 const int dx[8]={1,1,-1,-1,2,2,-2,-2};11 const int dy[8]={2,-2,2,-2,1,-1,1,-1};12 int T,x,y,flag,k,a[6][6];13 char map[6][6];14 inline int read()15 {16     int x=0,f=1;  char ch=getchar();17     while(!isdigit(ch))  {if(ch==-)  f=-1;  ch=getchar();}18     while(isdigit(ch))  {x=x*10+ch-0;  ch=getchar();}19     return x*f;20 }21 int check()22 {23     for(int i=0;i<5;i++)24         for(int j=0;j<5;j++)25             if(a[i][j]!=ans[i][j])  return 0;26     return 1;27 }28 int gujia(int s)29 {30     int v=0;31     for(int i=0;i<5;i++)32         for(int j=0;j<5;j++)33             if(a[i][j]!=ans[i][j])  {v++;  if(v+s>k)  return 0;}34     return 1;35 }36 void search(int s,int x,int y)37 {38     if(s==k)  {if(check())  flag=1;  return;}39     if(flag)  return;40     for(int i=0;i<8;i++)41     {42         int xx=x+dx[i],yy=y+dy[i];43         if(xx>4||xx<0||yy>4||yy<0)  continue;44         swap(a[x][y],a[xx][yy]);45         if(gujia(s))  search(s+1,xx,yy);46         swap(a[x][y],a[xx][yy]);47     }48 }49 int main()50 {51     //freopen("cin.in","r",stdin);52     //freopen("cout.out","w",stdout);53     T=read();54     while(T--)55     {56         for(int i=0;i<5;i++)57             for(int j=0;j<5;j++)58             {59                 cin>>map[i][j];60                 if(map[i][j]==*)  {a[i][j]=2;  x=i;  y=j;}61                 else a[i][j]=map[i][j]-0;62             }63         for(k=1;k<=15;k++)  {search(0,x,y);  if(flag)  {printf("%d\n",k);  break;}}64         if(!flag)  printf("-1\n");65         flag=0;66     }67     return 0;68 }

 

【bzoj1085】[SCOI2005]骑士精神