国际象棋
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为给定的马步数。
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! ",m); 56 else 57 printf("Knight cannot reach Queen within %d moves! ",m); 58 } 59 60 return 0; 61 }