• 国际象棋


    国际象棋

     

    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!
    ",m);
    56     else
    57       printf("Knight cannot reach Queen within %d moves!
    ",m);
    58   }
    59 
    60   return 0;
    61 }
    View Code
  • 相关阅读:
    图像处理之基础---卷积及其快速算法的C++实现
    嵌入式c语言笔试
    逻辑题
    多媒体开发之---h264 图像参数级语义
    多媒体开发之---h264 取流解码实现
    多媒体开发之---live555 分析客户端
    多媒体开发之---如何确定slice_header slice_type 的位置
    图像处理之基础---很好的一个开源文档库
    多媒体开发之---h264 高度和宽度获取
    Flutter实战视频-移动电商-65.会员中心_订单区域UI布局
  • 原文地址:https://www.cnblogs.com/gznb/p/11208215.html
Copyright © 2020-2023  润新知