国际象棋

国际象棋

 

Problem Description

在n*n的国际象棋棋盘中,给定一“马(Knight)”和一“后(Queen)”的位置,问“马”能否在m步之内(包括m步)到达“后”的位置?马的走法是:每步棋先横走或直走一格,然后再斜走一格,即走“日”字,没有“中国象棋”中“蹩马腿”的限制。比如在8*8的棋盘中,马的位置为(3, 5),则下一步可以落在(1 ,6)、(1, 4)、(2, 7)、(2, 3)、(4, 7)、(4, 3)、(5, 6)或(5, 4)。

Input

有多个测试用例,每个测试用例的输入数据有3行,第一行为2个正整数n和m(n <=1000000,m<=256);第二行为2个正整数kx和ky,代表“马”所在的位置(1<=kx, ky<=n);第三行为2个正整数qx和qy,代表“后”所在的位置(1<=qx, qy<=n)。我们保证马和后的位置不会重叠。

Output

如果“马”能够在m步之内(包括m步)到达“后”的位置,则输出:
Knight can reach Queen within m moves!
否则输出:
Knight cannot reach Queen within m moves!

其中m为给定的马步数。

Sample Input

8 2
3 5
7 4

Sample Output

Knight cannot reach Queen within 2 moves!

解释:

这是一个bfs+剪枝+离散化。假设起点为(dx, dy)  终点是(tx, ty) 当 abs(ty-dy) > 2 * m || abs(tx-dx) > 2 * m的时候,是肯定不能到达的。因为数据范围的问题,我觉得用搜索会超时,或者超内存。我就认为这个题可能是一个数学题,能根据某个数学公式直接判断。然后想了一会发现不行,我就设想是不是一个动态规划题,然后想了想,想不到答案。最后看到大佬说用bfs+剪枝+离散化。自己没有想到,用离散化去解决空间的问题,时间的办法我倒是知道用剪枝。记住了,解决空间用离散。

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 struct point{
 6   pair<int, int> p;
 7   int tep;
 8 }fr, be;
 9 
10 int n, m;
11 queue<point> que;
12 
13 map<pair<int, int>, int> flag; 
14 
15 int dir[8][2] = {1,-2,2,-1,2,1,1,2,-1,2,-2,1,-2,-1,-1,-2};
16 
17 int bfs() {
18   if (abs(fr.p.first - be.p.first) > m * 2 || abs(fr.p.second - be.p.second) > m * 2) return 0;
19   flag.clear();
20   flag[fr.p] = 0;
21   que.push(fr);
22  
23   while (!que.empty()) {
24     fr = que.front();
25     que.pop();
26     int temp = flag[fr.p];
27     if (temp >= m) break;
28     for (int i = 0; i < 8; i++) {
29       point t;
30       t.p.first = fr.p.first + dir[i][0];
31       t.p.second = fr.p.second + dir[i][1];
32       if (t.p == be.p) return 1;
33       if (t.p.first >= 1 && t.p.first <= n && t.p.second >= 1 && t.p.second <= n && flag.find(t.p) == flag.end()) {
34         t.tep = temp + 1;
35         flag[t.p] = t.tep;
36         if (abs(t.p.first - be.p.first) / 2 > (m - t.tep)  || abs(t.p.second - be.p.second) / 2  > (m - t.tep)) continue;
37         que.push(t);
38       }
39     }
40   }
41 
42   return 0;
43 
44 }
45 
46 
47 int main() {
48 
49   while (cin >> n >> m){
50      while(!que.empty()) que.pop();
51     cin >> fr.p.first >> fr.p.second;
52     cin >> be.p.first >> be.p.second;
53    
54     if (bfs())
55       printf("Knight can reach Queen within %d moves!\n",m);
56     else
57       printf("Knight cannot reach Queen within %d moves!\n",m);
58   }
59 
60   return 0;
61 }
View Code

 

posted @ 2019-07-18 16:34  龚政  阅读(450)  评论(0编辑  收藏  举报