[SCOI2005]骑士精神

题目描述

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1: 复制
2
10110
01*11
10111
01001
00000
01011
110*1
01110
01010
00100
输出样例#1: 复制
7
-1

说明

迭代次数dep

A*算法是利用估价函数h()进行剪枝

h()大于实际值就会错误

h()小于实际值太多效率会底下

所以h要慎重考虑

此题h可以这么计算:

当前棋盘有cnt个与目标棋盘不同的棋子

如果cnt等于0,那么退出

如果cnt不等于0,那么说明至少要走cnt-1步

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 char ch[10][10];
 8 int s[5][5];
 9 const int ss[5][5]=
10   {{1,1,1,1,1},
11    {0,1,1,1,1},
12    {0,0,2,1,1},
13    {0,0,0,0,1},
14    {0,0,0,0,0}};
15 int sx,sy,deeeep,flag;
16 const int dx[8]={2,-2,1,-1,2,-2,1,-1},dy[8]={1,1,2,2,-1,-1,-2,-2};
17 int h()
18 {int i,j;
19   int cnt=0;
20   for (i=0;i<=4;i++)
21     {
22       for (j=0;j<=4;j++)
23     {
24       if (s[i][j]!=ss[i][j]) cnt++;
25     }
26     }
27   return cnt;
28 }
29 void dfs(int x,int y,int sum,int dep)
30 {int i;
31   if (flag) return;
32   int H=h();
33   if (!H)
34     {
35       flag=1;
36       return;
37     }
38   if (sum+H-1>dep) return;
39   int xx,yy;
40   for (i=0;i<8;i++)
41     {
42       xx=x+dx[i],yy=y+dy[i];
43       if (xx<0||yy<0||xx>=5||yy>=5) continue;
44       swap(s[x][y],s[xx][yy]);
45       dfs(xx,yy,sum+1,dep);
46       swap(s[x][y],s[xx][yy]);
47     }
48 }
49 int main()
50 {int T,i,j;
51   cin>>T;
52   while (T--)
53     {
54       for (i=0;i<=4;i++)
55     {
56       scanf("%s",ch[i]);
57       for (j=0;j<=4;j++)
58         if (ch[i][j]=='*') sx=i,sy=j,s[i][j]=2;
59         else s[i][j]=ch[i][j]-'0';
60     }
61       deeeep=0;
62       flag=0;
63       while (deeeep<=15)
64     {
65       dfs(sx,sy,0,deeeep);
66       if (flag) break;
67       deeeep++;
68     }
69       if (flag==0) printf("-1\n");
70       else printf("%d\n",deeeep);
71     }
72 }

 

posted @ 2018-03-07 21:59  Z-Y-Y-S  阅读(270)  评论(0编辑  收藏  举报