hdu5040 不错的广搜
题意:
给你一个地图,让你从起点走到终点,然后图上有空地,墙,还有摄像头,摄像头有初始方向,每一秒摄像头都会顺时针旋转90度,每个摄像头有自己的观察范围,它所在的点,和当前它面向的那个点,如果我们当前这一步,和要走的下一步中有一个在当前这个时刻被摄像头监视着,那么我们就必须穿上个东西,穿上这个东西之后就可以不被发现了,但是穿上这个东西后移动速度变成每个格子3秒了,或者我们可以选择当前这一步静止不动。
思路:
wa了20多次,哎!,对于每一个点最多可以等两次(有的人说3次),其实就是两次,因为等两次之后最快的方式是+1走到下个点,等于直接用3的那个速度直接走过去,我们开一个数组mark[x][y][w] ,表示的是点x,y等待w次时的最优值,然后开个优先队列(保证第一个出来的答案就是最优的,同时也可以优化时间),然后当前点被监视,或者下一个点被监视的时候,我们就可以原地等待一次。具体看代码。
#include<stdio.h>
#include<string.h>
#include<queue> #define N 510
using namespace std; typedef struct NODE
{
int x ,y ,t ,w;
friend bool operator < (NODE a ,NODE b)
{
return a.t > b.t;
}
}NODE; NODE xin ,tou;
int mark[N][N][5];
int map[N][N] ,ex ,ey ,n;
int dir[4][2] = {0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0}; bool ok(int x ,int y)
{
return x >= 1 && x <= n && y >= 1 && y <= n && map[x][y];
} int sxj(int x ,int y ,int t)
{
if(map[x][y] >= 1 && map[x][y] <= 4) return 1;
if(x - 1 >= 1 && map[x-1][y] >= 1 && map[x-1][y] <= 4)
{
int now = (map[x-1][y] + t) % 4;
if(!now) now = 4;
if(now == 3) return 1;
}
if(x + 1 <= n && map[x+1][y] >= 1 && map[x+1][y] <= 4)
{
int now = (map[x+1][y] + t) % 4;
if(!now) now = 4;
if(now == 1) return 1;
}
if(y - 1 >= 1 && map[x][y-1] >= 1 && map[x][y-1] <= 4)
{
int now = (map[x][y-1] + t) % 4;
if(!now) now = 4;
if(now == 2) return 1;
}
if(y + 1 <= n && map[x][y+1] >= 1 && map[x][y+1] <= 4)
{
int now = (map[x][y+1] + t) % 4;
if(!now) now = 4;
if(now == 4) return 1;
}
return 0;
} int BFS(int x ,int y)
{
priority_queue<NODE>q;
xin.x = x ,xin.y = y ,xin.t = xin.w = 0;
for(int i = 1 ;i <= n ;i ++)
for(int j = 1 ;j <= n ;j ++)
for(int k = 0 ;k <= 4 ;k ++)
mark[i][j][k] = 100000000;
mark[xin.x][xin.y][xin.w] = 0;
q.push(xin);
while(!q.empty())
{
tou = q.top();
q.pop();
if(tou.x == ex && tou.y == ey) return tou.t;
for(int i = 0 ;i < 4 ;i ++)
{
xin.x = tou.x + dir[i][0];
xin.y = tou.y + dir[i][1];
xin.w = 0;
if(!ok(xin.x ,xin.y)) continue;
if(sxj(tou.x ,tou.y ,tou.t) || sxj(xin.x ,xin.y ,tou.t))
xin.t = tou.t + 3;
else xin.t = tou.t + 1;
if(xin.t < mark[xin.x][xin.y][xin.w])
{
mark[xin.x][xin.y][xin.w] = xin.t;
q.push(xin);
}
} xin.x = tou.x ,xin.y = tou.y ;
xin.t = tou.t + 1 ,xin.w = tou.w + 1;
if(xin.w <= 2 && xin.t < mark[xin.x][xin.y][xin.w])
{
mark[xin.x][xin.y][xin.w] = xin.t;
q.push(xin);
}
}
return -1;
} int main ()
{
int t ,i ,j ,x ,y ,cas = 1;
char str[N];
scanf("%d" ,&t);
while(t--)
{
scanf("%d" ,&n);
for(i = 1 ;i <= n ;i ++)
{
scanf("%s" ,str);
for(j = 0 ;j < n ;j ++)
{
if(str[j] == '.') map[i][j+1] = 5;
if(str[j] == '#') map[i][j+1] = 0;
if(str[j] == 'N') map[i][j+1] = 1;
if(str[j] == 'E') map[i][j+1] = 2;
if(str[j] == 'S') map[i][j+1] = 3;
if(str[j] == 'W') map[i][j+1] = 4;
if(str[j] == 'M') map[i][j+1] = 5 ,x = i ,y = j + 1;
if(str[j] == 'T') map[i][j+1] = 5 ,ex = i ,ey = j + 1;
}
}
printf("Case #%d: %d\n" ,cas ++ ,BFS(x ,y));
}
return 0;
}
hdu5040 不错的广搜的更多相关文章
- poj 3131 Cubic Eight-Puzzle 双向广搜 Hash判重
挺不错的题目,很锻炼代码能力和调试能力~ 题意:初始格子状态固定,给你移动后格子的状态,问最少需要多少步能到达,如果步数大于30,输出-1. 由于单向搜索状态太多,搜到二十几就会爆了,所以应该想到双向 ...
- HDU--杭电--1195--Open the Lock--深搜--都用双向广搜,弱爆了,看题了没?语文没过关吧?暴力深搜难道我会害羞?
这个题我看了,都是推荐的神马双向广搜,难道这个深搜你们都木有发现?还是特意留个机会给我装逼? Open the Lock Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 5652(二分+广搜)
题目链接:http://acm.hust.edu.cn/vjudge/contest/128683#problem/E 题目大意:给定一只含有0和1的地图,0代表可以走的格子,1代表不能走的格 子.之 ...
- nyoj 613 免费馅饼 广搜
免费馅饼 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy ...
- poj 3984:迷宫问题(广搜,入门题)
迷宫问题 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7635 Accepted: 4474 Description ...
- poj 3278:Catch That Cow(简单一维广搜)
Catch That Cow Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 45648 Accepted: 14310 ...
- 双向广搜 POJ 3126 Prime Path
POJ 3126 Prime Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16204 Accepted ...
- 广搜+打表 POJ 1426 Find The Multiple
POJ 1426 Find The Multiple Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 25734 Ac ...
- 双向广搜 codevs 3060 抓住那头奶牛
codevs 3060 抓住那头奶牛 USACO 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 黄金 Gold 题目描述 Description 农夫约翰被告知一头逃跑奶牛 ...
随机推荐
- LeetCode-二叉搜索树的范围和
二叉搜索树的范围和 LeetCode-938 首先需要仔细理解题目的意思:找出所有节点值在L和R之间的数的和. 这里采用递归来完成,主要需要注意二叉搜索树的性质. /** * 给定二叉搜索树的根结点 ...
- Java 多线程 02
多线程·线程间通信 和 GUI 单例设计模式 * A:单例设计模式 * 保证类在内存中只有一个对象 * B:如何保证 * a:控制类的创建,不让其他类来创建泵类的对象,私有化构造方法 * b:在本类中 ...
- 深入浅出新一代跨平台抓包&调式利器Fiddler Everywhere
什么是Fiddler Everywhere? Fiddler Everywhere is a web debugging proxy for macOS, Windows, and Linux. Ca ...
- 【MaixPy3文档】写好 Python 代码!
本文是给有一点 Python 基础但还想进一步深入的同学,有经验的开发者建议跳过. 前言 上文讲述了如何认识开源项目和一些编程方法的介绍,这节主要来说说 Python 代码怎么写的一些演化过程和可以如 ...
- 【python+selenium的web自动化】- 控制浏览器的常用操作
如果想从头学起selenium,可以去看看这个系列的文章哦! https://www.cnblogs.com/miki-peng/category/1942527.html 前言 本文主要介绍se ...
- Java 重入锁和读写锁
本文部分摘自<Java 并发编程的艺术> 重入锁 重入锁 ReentrantLock,顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁.除此之外,该锁还支持获取锁时 ...
- Shell编程中变量用法
1. 变量替换 语法 说明 ${变量名#匹配规则} 从变量开头进行规则匹配,将符合最短的数据删除 ${变量名##匹配规则} 从变量开头进行规则匹配,将符合最长的数据删除,贪婪匹配 ${变量名%匹配规则 ...
- 顶级开源项目 Sentry 20.x JS-SDK 设计艺术(Unified API篇)
SDK 开发 顶级开源项目 Sentry 20.x JS-SDK 设计艺术(理念与设计原则篇) 顶级开源项目 Sentry 20.x JS-SDK 设计艺术(开发基础篇) 顶级开源项目 Sentry ...
- Java 并发编程之 Condition 接口
本文部分摘自<Java 并发编程的艺术> 概述 任意一个 Java 对象,都拥有一个监视器方法,主要包括 wait().wait(long timeout).notify() 以及 not ...
- Python基础【while循环】
Python基础[while循环] 1.while循环: 格式 while 条件: ...... print(......) 注意,在while语句也可以嵌套else,但是else不执行循环,执行后直 ...