hdu-3085(双向bfs)
2017-05-17 20:36
393 查看
题目大意:
ghosts先每次分裂会覆盖两步之内所有的地方,然后erriyue每次走三步,girl friend每次走一步,ghosts能穿墙,人不能,问erriyue和girl friend是否能在指定的时间内相遇。
特别要注意的是,可以选择不走!不是一定要在那个时刻相遇! 英语渣,没读出来,但看别人的代码又确实是这个意思。
我一开始打算让幽灵也bfs,觉得这样不好写,搜网上有人用曼哈顿距离做,学习了一发。
比如说图上的两个黑点,分别表示当前的“我”(可以是erriyue,也可以是girl friend)和幽灵的初始位置,红蓝黄线都可以表示我到幽灵的曼哈顿距离,因为幽灵每次可以走两步,所以只要我到幽灵的曼哈顿距离小于二倍的已经走的次数,我就不会和幽灵相遇。
至于双向bfs我觉得和单向的区别不大,就是要注意交替逐层搜索,每次搜完都要判断一下。
ghosts先每次分裂会覆盖两步之内所有的地方,然后erriyue每次走三步,girl friend每次走一步,ghosts能穿墙,人不能,问erriyue和girl friend是否能在指定的时间内相遇。
特别要注意的是,可以选择不走!不是一定要在那个时刻相遇! 英语渣,没读出来,但看别人的代码又确实是这个意思。
我一开始打算让幽灵也bfs,觉得这样不好写,搜网上有人用曼哈顿距离做,学习了一发。
比如说图上的两个黑点,分别表示当前的“我”(可以是erriyue,也可以是girl friend)和幽灵的初始位置,红蓝黄线都可以表示我到幽灵的曼哈顿距离,因为幽灵每次可以走两步,所以只要我到幽灵的曼哈顿距离小于二倍的已经走的次数,我就不会和幽灵相遇。
至于双向bfs我觉得和单向的区别不大,就是要注意交替逐层搜索,每次搜完都要判断一下。
#include <iostream> #include <cstring> #include <cstdio> #include <queue> #include <cmath> using namespace std; const int tox[] = {0,1,0,-1}; const int toy[] = {1,0,-1,0}; char str[805][805]; int used[2][805][805]; int n,m,step; struct node { int x,y; } err,gf,z[2]; //分别表示初末位置,和两个小鬼的位置 queue<node> q[2]; void init() { int cnt=0; scanf("%d%d",&n,&m); for(int i=0; i<n; i++) { scanf("%s",str[i]); for(int j=0; j<m; j++) { if(str[i][j] =='M') //记录初末位置 { err.x = i; 4000 err.y = j; } else if(str[i][j] =='G') { gf.x = i; gf.y = j; } else if(str[i][j] =='Z') { z[cnt].x = i; z[cnt++].y = j; //下次是第二个小鬼 } } } } int judge(node b) { if(b.x<0 || b.y<0 || b.x>=n || b.y>=m || str[b.x][b.y] =='X') return 0; if((abs(b.x-z[0].x) + abs(b.y-z[0].y)) <= 2*step) return 0; if((abs(b.x-z[1].x) + abs(b.y-z[1].y)) <= 2*step) //用曼哈顿距离表示 是否会碰到分裂的小鬼 return 0; return 1; } int bfs(int w) { node one,next; int sum; sum = q[w].size(); while(sum--) { one = q[w].front(); q[w].pop(); if(judge(one) == 1) { for(int i=0; i<4; i++) { next.x = one.x + tox[i]; next.y = one.y + toy[i]; if(judge(next) == 0) continue; if(used[w][next.x][next.y] == 0) { if(used[w^1][next.x][next.y] == 1) //位运算w=0,这里就是1,w=1,这里就是0,判断两个人遇到了没 return 1; used[w][next.x][next.y] = 1; q[w].push(next); } } } } return 0; } int solve() { while(!q[0].empty()) q[0].pop(); while(!q[1].empty()) q[1].pop(); q[0].push(err); q[1].push(gf); memset(used,0,sizeof(used)); used[0][err.x][err.y]=used[1][gf.x][gf.y]=1; step=0; while ((!q[0].empty()) || (!q[1].empty())) { step++; if (bfs(0)==1) return step; if (bfs(0)==1) return step; if (bfs(0)==1) //走三步 return step; if (bfs(1)==1) //走一步 return step; } return -1; } int main() { int Case; scanf("%d",&Case); while (Case--) { init(); printf("%d\n",solve()); } return 0; }
相关文章推荐
- F - Nightmare Ⅱ HDU - 3085——双向BFS
- HDU 3085 Nightmare Ⅱ (双向BFS)
- hdu 3085(双向bfs)
- HDU 3085 Nightmare Ⅱ(双向BFS)
- HDU 3085 Nightmare Ⅱ 双向BFS
- HDU 3085 双向BFS
- HDU-3085-Nightmare Ⅱ(双向BFS)
- hdu 3085(双向bfs)
- HDU 3085 Nightmare 双向bfs
- hdu 3085 双向BFS
- hdu 3085 Nightmare Ⅱ(双向bfs)
- [hdu 3085]双向bfs
- HDU 3085 Nightmare II 双向bfs 难度:2
- HDU 3085 Nightmare Ⅱ(双向BFS)
- HDU 6171 Admiral [双向bfs+hash]
- hdu 1401 Solitaire 双向bfs
- Find a way HDU - 2612 双向BFS
- 双向BFS-->hdu 1195 Open the Lock
- HDU 6171 Admiral(hash+双向bfs)
- HDU 3081 Nightmare Ⅱ(双向BFS)