原题地址

https://vjudge.net/contest/313171     密码:algorithm

A - Rescue

Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are WALLs, ROADs, and GUARDs in the prison.

Angel's friends want to save Angel. Their task is: approach Angel. We assume that "approach Angel" is to get to the position where Angel stays. When there's a guard in the grid, we must kill him (or her?) to move into the grid. We assume that we moving up, down, right, left takes us 1 unit time, and killing a guard takes 1 unit time, too. And we are strong enough to kill all the guards. 
You have to calculate the minimal time to approach Angel. (We can move only UP, DOWN, LEFT and RIGHT, to the neighbor grid within bound, of course.)

Input

First line contains two integers stand for N and M.

Then N lines follows, every line has M characters. "." stands for road, "a" stands for Angel, and "r" stands for each of Angel's friend.

Process to the end of the file.

Output

For each test case, your program should output a single integer, standing for the minimal time needed. If such a number does no exist, you should output a line containing "Poor ANGEL has to stay in the prison all his life."

Sample Input

7 8
#.#####.
#.a#..r.
#..#x...
..#..#.#
#...##..
.#......
........

Sample Output

13

解题思路:

当r遇到护卫时将杀死他并浪费一分钟时间,所以需要用优先队列。

代码:

 #include <bits/stdc++.h>
using namespace std;
char arr[+][+];//存储地牢地图
int arr1[+][+];//标记走过的路
int dx[]={,,,-};
int dy[]={,-,,}; //代表方向
struct aa{//将数据放入一个结构优先队列中,并按w的大小排序
int x,y,w;
friend bool operator<(const aa &x,const aa &y){
return x.w>y.w;//按照w的升序排列
}
}aaa;
int bfs(int n,int m,int x1,int y1){
memset(arr1,,sizeof(arr1));//多组输入初始化数组
priority_queue<aa>que;//构建队列
aaa={x1,y1,};
que.push({x1,y1,});
int xx,yy,xxx,yyy,w,s;
while(que.size()){
xx=que.top().x;
yy=que.top().y;
w=que.top().w;//取出队列的top;
arr1[yy][xx]=;//将初始位置标记
que.pop();//删除top,要现取现删
for(int i=;i<;i++){
xxx=xx+dx[i];
yyy=yy+dy[i];//下一个位置的坐标
if(xxx>=&&xxx<m&&yyy>=&&yyy<n&&arr[yyy][xxx]!='#'&&arr1[yyy][xxx]==){//进行判断
if(arr[yyy][xxx]=='.'){
que.push({xxx,yyy,w+});//如果是路w+1,并存入队列
arr1[yyy][xxx]=; //标记
}
else if(arr[yyy][xxx]=='x'){
que.push({xxx,yyy,w+});//如果是护卫w+2
arr1[yyy][xxx]=;//标记
}
else if(arr[yyy][xxx]=='a'){
return w+;//等于a说明找到公主,此时所用时间最短,输出
}
}
}
}
return ;//没找到输出0;
}
int main(){
int n,m;
while(cin>>n>>m){
int x,y,ans;
for(int i=;i<n;i++){//构建地牢地图
cin>>arr[i];
for(int j=;j<m;j++){
if(arr[i][j]=='r'){
x=j;
y=i;
}
}
}
ans=bfs(n,m,x,y);
if(ans){//判断输出
cout<<ans<<endl;
}
else{
puts("Poor ANGEL has to stay in the prison all his life.");
}
}
return ; }

B - Red and Black

There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can't move on red tiles, he can move only on black tiles. 
Write a program to count the number of black tiles which he can reach by repeating the moves described above. 

Input

The input consists of multiple data sets. A data set starts with a line containing two positive integers W and H; W and H are the numbers of tiles in the x- and y- directions, respectively. W and H are not more than 20. 
There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows.

'.' - a black tile 
'#' - a red tile 
'@' - a man on a black tile(appears exactly once in a data set)

Output

For each data set, your program should output a line which contains the number of tiles he can reach from the initial tile (including itself).

解题思路:

与上一题大致相同,且可以不用优先队列。

C - Battle City

poj2312

解题思路与第一题相同

D - Catch That Cow

农夫知道一头牛的位置,想要抓住它。农夫和牛都于数轴上 ,农夫起始位于点 N(0<=N<=100000) ,牛位于点 K(0<=K<=100000) 。农夫有两种移动方式: 1、从 X移动到 X-1或X+1 ,每次移动花费一分钟 2、从 X移动到 2*X ,每次移动花费一分钟 假设牛没有意识到农夫的行动,站在原地不。最少要花多少时间才能抓住牛?

Input

一行: 以空格分隔的两个字母: N 和 K

Output

一行: 农夫抓住牛需要的最少时间,单位分钟

Sample Input

5 17

Sample Output

4

Hint

农夫使用最短时间抓住牛的方案如下: 5-10-9-18-17, 需要4分钟.
解题思路:
走的方向有三种,注意范围。
 

E - Dungeon Master

 Description - 题目描述

[NWUACM] 
你被困在一个三维的空间中,现在要寻找最短路径逃生!
空间由立方体单位构成
你每次向上下前后左右移动一个单位需要一分钟
你不能对角线移动并且四周封闭
是否存在逃出生天的可能性?如果存在,则需要多少时间?

Input - 输入

  输入第一行是一个数表示空间的数量。
  每个空间的描述的第一行为L,R和C(皆不超过30)。
  L表示空间的高度。
  R和C分别表示每层空间的行与列的大小。
  随后L层地牢,每层R行,每行C个字符。
  每个字符表示空间的一个单元。'#'表示不可通过单元,'.'表示空白单元。你的起始位置在'S',出口为'E'。
  每层空间后都有一个空行。L,R和C均为0时输入结束。

Output - 输出

  每个空间对应一行输出。
  如果可以逃生,则输出如下
  Escaped in x minute(s).
  x为最短脱离时间。
  如果无法逃生,则输出如下 :Trapped!

解题思路:

三维与二维相似,将方向改为 int dx[6]={0,0,1,-1,0,0}; int dy[6]={1,-1,0,0,0,0}; int dz[6]={0,0,0,0,1,-1};即可.


F - Robot Motion

A robot has been programmed to follow the instructions in its path. Instructions for the next direction the robot is to move are laid down in a grid. The possible instructions are

N north (up the page) 
S south (down the page) 
E east (to the right on the page) 
W west (to the left on the page) 
For example, suppose the robot starts on the north (top) side of Grid 1 and starts south (down). The path the robot follows is shown. The robot goes through 10 instructions in the grid before leaving the grid. 
Compare what happens in Grid 2: the robot goes through 3 instructions only once, and then starts a loop through 8 instructions, and never exits. 
You are to write a program that determines how long it takes a robot to get out of the grid or how the robot loops around. 

Input

There will be one or more grids for robots to navigate. The data for each is in the following form. On the first line are three integers separated by blanks: the number of rows in the grid, the number of columns in the grid, and the number of the column in which the robot enters from the north. The possible entry columns are numbered starting with one at the left. Then come the rows of the direction instructions. Each grid will have at least one and at most 10 rows and columns of instructions. The lines of instructions contain only the characters N, S, E, or W with no blanks. The end of input is indicated by a row containing 0 0 0.

Output

For each grid in the input there is one line of output. Either the robot follows a certain number of instructions and exits the grid on any one the four sides or else the robot follows the instructions on a certain number of locations once, and then the instructions on some number of locations repeatedly. The sample input below corresponds to the two grids above and illustrates the two forms of output. The word "step" is always immediately followed by "(s)" whether or not the number before it is 1.

Sample Input

3 6 5
NEESWE
WWWESS
SNWWWW
4 5 1
SESWE
EESNW
NWEEN
EWSEN
0 0 0

Sample Output

10 step(s) to exit
3 step(s) before a loop of 8 step(s) 解题思路:
使用递归遍历走的路,看是否是循环或能否走出去。 
 #include<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<queue>
#include<algorithm>
#include <vector>
using namespace std;
int n,m;
char arr[][];
int arr1[][];
int flag=,l,r,ans;
void bfs(int x,int y,int num){
if(x<||y<||x>=m||y>=n){
ans=num;
return ;
}
if(arr1[y][x]){
flag=;
l=arr1[y][x];
r=num-arr1[y][x];
return ;
}
arr1[y][x]=num;
if(arr[y][x] == 'N')
bfs(x,y-,num+);
else if(arr[y][x] == 'S')
bfs(x,y+,num+);
else if(arr[y][x] == 'E')
bfs(x+,y,num+);
else if(arr[y][x] == 'W')
bfs(x-,y,num+);
}
int main(){
int x,y=;
while(cin>>n>>m>>x){
if(n==&m==&x==){
break;
}
flag=;
y=;
x=x-;
memset(arr1,,sizeof(arr1));
for(int i=;i<n;i++){
cin>>arr[i];
}
bfs(x,y,);
if(flag){
printf("%d step(s) before a loop of %d step(s)\n",l-,r);
}
else {
printf("%d step(s) to exit\n",ans-);
}
}
return ;
}

G - Number Transformation

In this problem, you are given an integer number s. You can transform any integer number A to another integer number B by adding x to A. This x is an integer number which is a prime factor of A (please note that 1 and A are not being considered as a factor of A). Now, your task is to find the minimum number of transformations required to transform s to another integer number t.

Input

Input starts with an integer T (≤ 500), denoting the number of test cases.

Each case contains two integers: s (1 ≤ s ≤ 100) and t (1 ≤ t ≤ 1000).

Output

For each case, print the case number and the minimum number of transformations needed. If it's impossible, then print -1.

Sample Input

2

6 12

6 13

Sample Output

Case 1: 2

Case 2: -1

解题思路:

a的prime factor(素因子)是指能整除a且不是素数的数字i,i!=1&&i!=a.本题的意思是循环一个数,这个数加上他的素因子,直到与给出的另一个数相等位置(数在改变,所以素因子也在改变)。

代码:

 #include<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<queue>
#include<algorithm>
#include <vector>
using namespace std;
typedef pair<int,int> P;
vector<int>arr;
int arr1[];
int is_primer(int a){
if(a==)return ;
for(int i=;i<a;i++){
if(a%i==){
return ;
}
}
return ;
}
int bfs(int a,int b){
memset(arr1,,sizeof(arr1));
queue<P>que;
int d,ss;
que.push({a,});
arr1[a]=;
while(que.size()){
arr.clear();
int x,y;
x=que.front().first;
y=que.front().second;
for(int j=;j<x;j++){
if(x%j==&&is_primer(j)){
arr.push_back(j);
}
}
que.pop();
for(int i=;i<arr.size();i++){
d=x+arr[i];
if(d>&&d<b+&&!arr1[d]){
if(d==b){
return y+;
}
else{
que.push({d,y+});
arr1[d]=;
}
}
}
}
return ;
}
int main(){
int n,s,k=,t;
cin>>n;
for(int i=;i<=n;i++){
k=;
cin>>s>>t;
if(s==t){
printf("Case %d: 0\n",i);
}
else{
int ans=bfs(s,t);
printf("Case %d: ",i);
if(ans){
cout<<ans<<endl;
}
else {
cout<<-<<endl;
}
}
}
return ;
}

H - Knight Moves

A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the shortest closed tour of knight moves that visits each square of a given set of n squares on a chessboard exactly once. He thinks that the most difficult part of the problem is determining the smallest number of knight moves between two given squares and that, once you have accomplished this, finding the tour would be easy. 
Of course you know that it is vice versa. So you offer him to write a program that solves the "difficult" part.

Your job is to write a program that takes two squares a and b as input and then determines the number of knight moves on a shortest route from a to b.

Input

The input file will contain one or more test cases. Each test case consists of one line containing two squares separated by one space. A square is a string consisting of a letter (a-h) representing the column and a digit (1-8) representing the row on the chessboard. 
Output

For each test case, print one line saying "To get from xx to yy takes n knight moves.". 
Sample Input

e2 e4
a1 b2
b2 c3
a1 h8
a1 h7
h8 a1
b1 c3
f6 f6

Sample Output

To get from e2 to e4 takes 2 knight moves.
To get from a1 to b2 takes 4 knight moves.
To get from b2 to c3 takes 2 knight moves.
To get from a1 to h8 takes 6 knight moves.
To get from a1 to h7 takes 5 knight moves.
To get from h8 to a1 takes 6 knight moves.
To get from b1 to c3 takes 1 knight moves.
To get from f6 to f6 takes 0 knight moves.

解题思路:

题意大致是从一个点到另一个点以走'日'的形式需要的最短时间,一共有八个方向。

代码略。


BFS(宽度优先搜索) -例题的更多相关文章

  1. 【BFS宽度优先搜索】

    一.求所有顶点到s顶点的最小步数   //BFS宽度优先搜索 #include<iostream> using namespace std; #include<queue> # ...

  2. 搜索与图论②--宽度优先搜索(BFS)

    宽度优先搜索 例题一(献给阿尔吉侬的花束) 阿尔吉侬是一只聪明又慵懒的小白鼠,它最擅长的就是走各种各样的迷宫. 今天它要挑战一个非常大的迷宫,研究员们为了鼓励阿尔吉侬尽快到达终点,就在终点放了一块阿尔 ...

  3. BFS算法的优化 双向宽度优先搜索

    双向宽度优先搜索 (Bidirectional BFS) 算法适用于如下的场景: 无向图 所有边的长度都为 1 或者长度都一样 同时给出了起点和终点 以上 3 个条件都满足的时候,可以使用双向宽度优先 ...

  4. 【算法入门】广度/宽度优先搜索(BFS)

    广度/宽度优先搜索(BFS) [算法入门] 1.前言 广度优先搜索(也称宽度优先搜索,缩写BFS,以下采用广度来描述)是连通图的一种遍历策略.因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较 ...

  5. 层层递进——宽度优先搜索(BFS)

    问题引入 我们接着上次“解救小哈”的问题继续探索,不过这次是用宽度优先搜索(BFS). 注:问题来源可以点击这里 http://www.cnblogs.com/OctoptusLian/p/74296 ...

  6. 算法基础⑦搜索与图论--BFS(宽度优先搜索)

    宽度优先搜索(BFS) #include<cstdio> #include<cstring> #include<iostream> #include<algo ...

  7. 挑战程序2.1.5 穷竭搜索>>宽度优先搜索

    先对比一下DFS和BFS         深度优先搜索DFS                                   宽度优先搜索BFS 明显可以看出搜索顺序不同. DFS是搜索单条路径到 ...

  8. [宽度优先搜索] FZU-2150 Fire Game

    Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows, M columns) ...

  9. 宽度优先搜索--------迷宫的最短路径问题(dfs)

    宽度优先搜索运用了队列(queue)在unility头文件中 源代码 #include<iostream>#include<cstdio>#include<queue&g ...

随机推荐

  1. express 中间件的理解

    nodejs(这指express) 中间件 铺垫: 一个请求发送到服务器,要经历一个生命周期,服务端要: 监听请求-解析请求-响应请求,服务器在处理这一过程的时候,有时候就很复杂了,将这些复杂的业务拆 ...

  2. Tido 习题-二叉树-树状数组实现

    题目描述 这就是一个简单的树状数组入门题 可以动态地进行区间和查询 随时可能会进行更新   #include<iostream> #include<cstdio> #inclu ...

  3. springboot中加分布式redis锁

    分布式redis锁,spring-boot-starter-data-redis,RedisTemplate 公司聊天的聊天系统,近期出现多个客服并发接待同一个客户的记录,经排查,是由于代码加的同步锁 ...

  4. mysql数据库之表关系

    外键 前戏之一对多关系 # 定义一张部门员工表id name gender dep_name dep_desc1 jason male 教学部 教书育人2 egon male 外交部 漂泊游荡3 ta ...

  5. VsCode 常用快捷键、debug菜单、debug插件

    常用快捷键emmet                   百度emmet即可知  Ctrl + P            转到文件Ctrl+鼠标左键不松手     预览代码Ctrl+鼠标左键松手    ...

  6. redis安装与php安装redis模块

    一.安装redis 1.下载 wget https://github.com/antirez/redis/archive/2.8.23.tar.gz 2.解压缩 tar -zxvf 2.8.23.ta ...

  7. Jenkins与RocketChat集成

    Jenkins与RocketChat集成 在Jenkins中安装插件RocketChat Notifier 配置信息 点击Jenkins左侧的系统管理-->系统设置, 找到Global Rock ...

  8. Codeforces 1133E - K Balanced Teams - [DP]

    题目链接:https://codeforces.com/contest/1133/problem/C 题意: 给出 $n$ 个数,选取其中若干个数分别组成 $k$ 组,要求每组内最大值与最小值的差值不 ...

  9. Qt之股票组件-股票检索--支持预览框、鼠标、键盘操作

    目录 一.感慨一下 二.效果展示 三.搜索编辑框 1.编辑框 2.预览框 四.相关文章 原文链接:Qt之股票组件-股票检索--支持预览框.鼠标.键盘操作 一.感慨一下 之前做过一款炒股软件,个人觉着是 ...

  10. HDU 1533:Going Home(KM算法求二分图最小权匹配)

    http://acm.hdu.edu.cn/showproblem.php?pid=1533 Going Home Problem Description   On a grid map there ...