码迷,mamicode.com
首页 > 其他好文 > 详细

1085: [SCOI2005]骑士精神

时间:2018-08-10 23:10:19      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:scan   sam   input   ios   \n   技术   std   pac   scanf   

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 3371  Solved: 1990
[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
 
第一次写启发式搜索
直接dfs爆搜会TLE,于是就要用到神奇的A-star(简称A*)算法
 
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 
 6 const char mat[5][5]={1,1,1,1,1,
 7                      0,1,1,1,1,
 8                      0,0,*,1,1,
 9                      0,0,0,0,1,
10                      0,0,0,0,0};
11 
12 int T,x,y,k;
13 int mx[8]={-2,-1,1,2,2,1,-1,-2};
14 int my[8]={1,2,2,1,-1,-2,-2,-1};
15 char mp[10][10];
16 bool flag;
17 
18 void read()
19 {
20     flag=0;
21     for(int i=0;i<5;i++)
22         scanf("%s",mp[i]);
23     for(int i=0;i<5;i++)
24         for(int j=0;j<5;j++)
25             if(mp[i][j]==*) x=i,y=j;
26 }
27 
28 bool check()
29 {
30     for(int i=0;i<5;i++)
31         for(int j=0;j<5;j++)
32             if(mp[i][j]!=mat[i][j]) return false;
33     return true;
34 }
35 
36 bool judge(int now)
37 {
38     int val=0;
39     for(int i=0;i<5;i++)
40         for(int j=0;j<5;j++)
41             if(mp[i][j]!=mat[i][j])
42             {
43                 val++;
44                 if(val+now>k) return false;
45             }
46     return true;
47 }
48 
49 void dfs(int now,int x,int y)
50 {
51     if(now>=k)
52     {
53         if(check()) flag=1;
54         return;
55     }
56     if(flag) return;
57     for(int i=0;i<8;i++)
58     {
59         int nx=x+mx[i],ny=y+my[i];
60         if(nx<0||nx>4||ny<0||ny>4) continue;
61         swap(mp[x][y],mp[nx][ny]);
62         if(judge(now)) dfs(now+1,nx,ny);
63         swap(mp[x][y],mp[nx][ny]);
64     }
65 }
66 
67 int main()
68 {
69     scanf("%d",&T);
70     while(T--)
71     {
72         read();
73         for(k=1;k<=15;k++)
74         {
75             dfs(0,x,y);
76             if(flag)
77             {
78                 printf("%d\n",k);
79                 break;
80             }
81         }
82         if(!flag) printf("-1\n");
83     }
84     return 0;
85 }

 

1085: [SCOI2005]骑士精神

标签:scan   sam   input   ios   \n   技术   std   pac   scanf   

原文地址:https://www.cnblogs.com/InWILL/p/9457530.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!