【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 }

 

posted @ 2016-09-10 17:12  chty  阅读(87)  评论(0编辑  收藏