• HDU 3085 Nightmare Ⅱ(双向BFS)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085

    题目大意:给你一张n*m地图上,上面有有

      ‘. ’:路

      ‘X':墙

      ’Z':鬼,每秒移动2步,可以穿墙,开始有两个,每开始时鬼先动。

      ‘M’:男生,每秒可走3步。

      ‘G’:女生,每秒可走1步。

    解题思路:第一次写双向BFS,写了我好久,开始还是想着先bfs计算step[x][y][t]把每个位置被鬼占据的时间处理一下然后再用双向BFS计算两人相遇时间。后来发现因为鬼可以穿墙,可以直接用曼哈顿距离判断是否会被鬼抓到。还有,开始我都不知道每秒走三步怎么搞。。。后来看了网上的博客,知道可以通用size限制一下出队数,三次bfs实现每秒走三步。太乱了,稍微总结一下:

         ①两人给vis[x][y]分别标记1,2当某次bfs遇到不同标记说明两人相遇。

         ②用曼哈顿距离判断时间t走到某个位置是否会被鬼抓到。

         ③因为鬼先行动,每次t+1时,在人行动前要判断在当前位置会不会被鬼抓到。

         ④用size=q[mark].size()控制每次出队数,实现一秒走三步。

         ⑤最坑爹的一点,用scanf("%c",&map[i][j])无限超时,感觉里面绝对有不正常的数据,后来用scanf("%s",map[i]+1)每次输入一行才过掉。

    代码:

      1 #include<iostream>
      2 #include<queue>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<algorithm>
      6 using namespace std;
      7 const int N=805;
      8 
      9 int n,m,t;
     10 int d[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
     11 char map[N][N];
     12 int vis[N][N];
     13 
     14 struct node{
     15     int x,y;
     16 }M,G,pre,now,a[3];
     17 queue<node>q[3];
     18 
     19 bool judge(int x,int y){
     20     if(x<1||y<1||x>n||y>m||map[x][y]=='X')
     21         return false;
     22     //利用曼哈顿距离判断是否会被鬼抓到 
     23     for(int i=1;i<=2;i++){
     24         if(abs(x-a[i].x)+abs(y-a[i].y)<=2*t)
     25             return false;
     26     }
     27     return true;
     28 }
     29 
     30 bool bfs(int mark){
     31     //小技巧,利用size就可以控制出队的都是上一步的,而不会将这一步的也出队,就能实现走3步了。 
     32     int size=q[mark].size(); 
     33     while(size--){
     34         pre=q[mark].front();
     35         q[mark].pop();
     36         //鬼在人之前行动,时间每增加1,先判断鬼能不能把人吃掉
     37         if(!judge(pre.x,pre.y)) 
     38             continue;
     39         for(int i=0;i<4;i++){
     40             int xx=pre.x+d[i][0];
     41             int yy=pre.y+d[i][1];
     42             if(!judge(xx,yy))
     43                 continue;
     44             //遇到不同标记说明两人相遇 
     45             if(vis[xx][yy]){
     46                 if(vis[xx][yy]!=mark)
     47                     return true;
     48                 else
     49                     continue;
     50             }
     51             vis[xx][yy]=mark;
     52             now.x=xx;
     53             now.y=yy;
     54             q[mark].push(now);
     55         }
     56     }
     57     return false;
     58 }
     59 
     60 int solve(){
     61     //清空队列 
     62     while(!q[1].empty()) q[1].pop();
     63     while(!q[2].empty()) q[2].pop();
     64     q[1].push(M);
     65     q[2].push(G);
     66     vis[M.x][M.y]=1,vis[G.x][G.y]=2;
     67     t=0;
     68     //双向bfs 
     69     while(!q[1].empty()||!q[2].empty()){
     70         t++;
     71         for(int i=1;i<=3;i++){
     72             if(bfs(1))
     73                 return t;
     74         }        
     75         if(bfs(2))
     76             return t;
     77     }
     78     return -1;
     79 }
     80 
     81 int main(){
     82     int T;
     83     scanf("%d",&T);
     84     while(T--){
     85         memset(vis,0,sizeof(vis));
     86         scanf("%d%d",&n,&m);
     87         //注意用scanf("%c",map[i][j])会超时 
     88         for(int i=1,cnt=0;i<=n;i++){
     89             scanf("%s",map[i]+1);
     90             for(int j=1;j<=m;j++){
     91                 if(map[i][j]=='M')
     92                     M.x=i,M.y=j;
     93                 if(map[i][j]=='G')
     94                     G.x=i,G.y=j;
     95                 if(map[i][j]=='Z')
     96                     a[++cnt].x=i,a[cnt].y=j;
     97             }
     98         }
     99         printf("%d
    ",solve());
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    使用JavaWeb实现文件的上传和下载
    IDEA使用Maven创建Web项目的两种方式
    Window10系统下联想笔记本进入BIOS界面方法
    MarkDown语法
    PV-UV-QPS
    expect 安装 salt 客户端
    fg、bg、jobs、&、nohup、ctrl+z、ctrl+c 命令
    查看CPU 内存 硬盘 网络 查看进程使用的文件 uptime top ps -aux vmstat iostat iotop nload iptraf nethogs
    rpm 命令使用 和 lsof -p 1406 使用
    salt 执行shell 脚本 修改名字
  • 原文地址:https://www.cnblogs.com/fu3638/p/7576694.html
Copyright © 2020-2023  润新知