• TZOJ 2755 国际象棋(广搜+哈希)


    描述

    在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)。

    输入

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

    输出

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

    否则输出:
    Knight cannot reach Queen within m moves!

    其中m为给定的马步数。

    样例输入

    8 2
    3 5
    7 4

    样例输出

    Knight cannot reach Queen within 2 moves!

    题意

    马能否在m步之内到后

    题解

    这题n<=1e6肯定MLE,所以得用广搜,已经到过的点加入队列

    这里我把点哈希成1个数字存入set中,方便查找

    代码

     1 #include<stdio.h>
     2 #include<queue>
     3 #include<set>
     4 using namespace std;
     5 
     6 int abs(int x){return x>=0?x:-x;}
     7 struct point{int x,y,k;}s,e;
     8 int n,m;
     9 int dx[]={1,2,2,1,-1,-2,-2,-1};
    10 int dy[]={-2,-1,1,2,2,1,-1,-2};
    11 int bfs()
    12 {
    13     if(abs(s.x-e.x)/2>m)return 0;//x不行
    14     if(abs(s.y-e.y)/2>m)return 0;//y不行
    15     point h,t;
    16     queue<point> qu;
    17     set<__int64> se;//哈希1000000
    18     __int64 hs=((__int64)s.x)*1000000+(__int64)s.y;
    19     se.insert(hs);
    20     s.k=0;
    21     qu.push(s);
    22     while(!qu.empty())
    23     {
    24         h=qu.front();
    25         qu.pop();
    26         if(h.x==e.x&&h.y==e.y)
    27             return 1;
    28         if(h.k==m)continue;//步数不超限
    29         for(int i=0;i<8;i++)
    30         {
    31             t.x=h.x+dx[i];
    32             t.y=h.y+dy[i];
    33             if(t.x==e.x&&t.y==e.y)//找到赶紧跳出
    34                 return 1;
    35             hs=((__int64)t.x)*1000000+(__int64)t.y;
    36             if(t.x>=1&&t.x<=n&&t.y>=1&&t.y<=n&&se.find(hs)==se.end())
    37             {
    38                 t.k=h.k+1;
    39                 se.insert(hs);
    40                 qu.push(t);
    41             }
    42         }
    43     }
    44     return 0;
    45 }
    46 int main(){
    47     while(scanf("%d%d",&n,&m)!=EOF)
    48     {
    49         scanf("%d%d%d%d",&s.x,&s.y,&e.x,&e.y);
    50         if(bfs())printf("Knight can reach Queen within %d moves!
    ",m);
    51         else printf("Knight cannot reach Queen within %d moves!
    ",m);
    52     }
    53     return 0;
    54 }
  • 相关阅读:
    【转载】eclipse常用插件在线安装地址或下载地址
    【转载】Eclipse快捷键 10个最有用的快捷键
    Visual Studio(C#)快捷键与Eclipse(JAVA)快捷键对比
    【转载】Eclipse 的快捷键以及文档注释、多行注释的快捷键
    Spring 事务配置的几种方式
    Linux下 执行程序
    转:C# 通过委托更新UI(异步加载)
    C#AutoResetEvent和ManualResetEvent的区别
    转 RMI、RPC、SOAP通信技术介绍及比对
    转泛型
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/8417275.html
Copyright © 2020-2023  润新知