hdu 5040 Instrusive(bfs+优先队列)(模拟)
2015-09-19 10:57
405 查看
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5040
解题思路:
题目大意:
给你一个图,里面有起点,终点,和监视器的位置,每个监视器有东南西北的初始朝向,每个监视器的监视范围是两格(自身所在
区域算一个),每过1秒钟,所有监视器的所朝方向都会顺时针旋转90度,从被监视位置到其他的任何位置都需要消耗3秒钟,从其
他位置进入被监视位置需要3秒钟,其他的情况消耗1秒钟,当处于被监视位置时也可以停留若干秒,等处于非监视状态再继续,问
从起点到终点的最短时间。
算法思想:
bfs+优先队列,状态保存需要坐标(x,y)还有时间tmpt%4这三个元素就行了。
AC代码:
http://acm.hdu.edu.cn/showproblem.php?pid=5040
解题思路:
题目大意:
给你一个图,里面有起点,终点,和监视器的位置,每个监视器有东南西北的初始朝向,每个监视器的监视范围是两格(自身所在
区域算一个),每过1秒钟,所有监视器的所朝方向都会顺时针旋转90度,从被监视位置到其他的任何位置都需要消耗3秒钟,从其
他位置进入被监视位置需要3秒钟,其他的情况消耗1秒钟,当处于被监视位置时也可以停留若干秒,等处于非监视状态再继续,问
从起点到终点的最短时间。
算法思想:
bfs+优先队列,状态保存需要坐标(x,y)还有时间tmpt%4这三个元素就行了。
AC代码:
#include <iostream> #include <cstdio> #include <queue> #include <cstring> #include <algorithm> using namespace std; const int maxn = 505; const int dx[] = {0,-1,0,1},dy[] = {-1,0,1,0}; //E==0,S==1,W==2,N==3 int n; int dir[110]; bool vis[maxn][maxn][5]; char a[maxn][maxn]; struct node{ int x,y,t; bool operator < (const node &s) const{ return t > s.t; } }; int Check(int x,int y,int t){ //return 1代表该位置当前被灯照到,2代表当前位置没有灯照射,也可以走,0代表不可达 if(x<1 || x>n || y<1 || y>n || a[x][y]=='#') return 0; if(dir[a[x][y]] != -1) return 1; for(int i = 0; i < 4; i++){ //要知道当前点有没有被照到,需要查看当前点四个方向上有没有灯朝向这个点 int xx = x+dx[i],yy = y+dy[i]; if(xx<1 || xx>n || yy<1 || yy>n) continue; int tmp = dir[a[xx][yy]];//tmp>=0代表当前点有灯 if(tmp>=0 && (tmp+t)%4==i) return 1; //(tmp+t)代表当前时间,%4代表此时灯的转向,稍微设计了一下方向函数dir,使得(tmp+t)==i的时候,说明该点被照到 } return 2; } int bfs(int sx,int sy){ memset(vis,0,sizeof(vis)); priority_queue<node> que; que.push((node){sx,sy,0}); while(!que.empty()){ node cur = que.top(); que.pop(); if(a[cur.x][cur.y] == 'T') return cur.t; int tmpt; //不移动的情况 tmpt = cur.t+1; if(!vis[cur.x][cur.y][tmpt%4]){ vis[cur.x][cur.y][tmpt%4] = 1; que.push((node){cur.x,cur.y,tmpt}); } int flag = Check(cur.x,cur.y,cur.t);//flag=1说明当前点被照亮 for(int i = 0; i < 4; i++){ int xx = cur.x+dx[i],yy = cur.y+dy[i]; int check = Check(xx,yy,cur.t); if(check == 0) continue; if(check==1 || flag==1) tmpt = cur.t+3;//要移动的点或者当前点被照亮 else if(check == 2) tmpt = cur.t+1; if(!vis[xx][yy][tmpt%4]){ vis[xx][yy][tmpt%4]=1; que.push((node){xx,yy,tmpt}); } } } return -1; } int main(){ memset(dir,-1,sizeof(dir)); dir['E'] = 0,dir['S'] = 1,dir['W'] = 2,dir['N'] = 3; int T,t = 1; scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i = 1; i <= n; i++) scanf("%s",a[i]+1); int sx,sy; for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) if(a[i][j] == 'M'){ sx = i,sy = j; break; } int ans = bfs(sx,sy); printf("Case #%d: %d\n",t++,ans); } return 0; }
相关文章推荐
- Can't read dir of '.' (errno: 13)
- 【poj3734】矩阵乘法求解
- java集合框架之Set
- BusyBox getty
- A*B Problem 485 (数学题+九余数定理)
- Ubuntu下通过apt-get安装软件
- Yii2 数据库操作汇总
- 软工之可行性分析和需求分析
- java Serializable 理解
- 修路方案 118 (prim判断最小生成树的不唯一性)
- Pagerstwich tab样式加下拉刷新(三)
- AJAX工作原理
- iOS property属性
- (转)MyEclipse快捷键大全
- JAVA数据类型
- *LeetCode-Search a 2D Matrix
- Move Zeroes
- ubuntu中ssh登录错误
- html5 canvas画图手电筒效果
- 单链表C语言的实现