题意:求出Ignatius走出迷宫的时间。
注意:0表示墙,1表示空白,2表示起点,3表示目标点,4表示炸弹时间重置装置,(1<=n,m<=8)。
思路:这道题如果没有4,那么就是一道简单的深搜。只要不重新走时间装置就可以了。
/*
思路:
*/
#include<iostream>
#include<queue>
using namespace std;
struct node{
int x;
int y;
int time;// 记录时间
int step;// 记录步数
} hero;
/*
n表示行
m表示列
map长度是9,最多输入8个数据
dir分别表示上下左右,第一个表示(x-1,y+0),x是控制行的
mark记录英雄第一次走过该点时所剩余的时间
*/
int n,m;
int dir[][2]={{-1,0},{1,0},{0,-1},{0,1}};
int map[9][9];
int main(){
int t;
cin>>t;
void myInput();
void breadthFirstSearch();
while(t--){
cin>>n>>m;
myInput();
breadthFirstSearch();
}
return 0;
}
void myInput(){
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>map[i][j];
// 找到英雄,记录他的信息
if(map[i][j]==2){
// 结构体中的整形数据可以直接赋值,字符串就不可以
hero.x=i;
hero.y=j;
hero.time=6;
hero.step=0;
}
}
}
}
void breadthFirstSearch(){
queue<node> que;
// 第一步把hero压入栈中
que.push(hero);
/*
heroBunshin-英雄分身,这个你懂得,
让分身去试探,只有正身才会走正确的道路
*/
node heroBunshin,newNode;
while(!que.empty()){
// 第二步弹出头元素出栈
heroBunshin=que.front();
que.pop();
/*
搜索四面是否可以行动
*/
for(int i=0;i<4;i++){
// 先复制一份
newNode=heroBunshin;
newNode.x=newNode.x+dir[i][0];
newNode.y=newNode.y+dir[i][1];
newNode.step++;
newNode.time--;
//判断边界
if(newNode.x>=0&&newNode.y>=0&&newNode.x<n&&newNode.y<m){
//判断墙
if(map[newNode.x][newNode.y]!=0){
// 超时
if(newNode.time>0){
//走出迷宫,map==3才可以结束程序或着栈内元素全部出栈
if(map[newNode.x][newNode.y]==3){
cout<<newNode.step<<endl;
return;
}
//判断时间重置
if(map[newNode.x][newNode.y]==4){
newNode.time=6;
map[newNode.x][newNode.y]=0;//不能再访问了
}
que.push(newNode);
}
}
}
}
}
cout<<-1<<endl;
}
java代码
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
static int n, m;
static Node nodes[][] = new Node[8][8];
static int dir[][] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
int sx = 0, sy = 0;
while (t-- > 0) {
n = sc.nextInt();
m = sc.nextInt();
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
nodes[i][j] = new Node(sc.nextInt(), i, j, -1, 0);
if (nodes[i][j].value == 2) {
sx = i;
sy = j;
nodes[i][j].time = 6;
}
}
}
Node nod = breadthFirstSearch(sx, sy);
if (nod != null) {
System.out.println(nod.step);
} else {
System.out.println("-1");
}
}
}
/*
* breadthFirstSearch-广度优先搜索
*/
private static Node breadthFirstSearch(int x, int y) {
MyQueue mq = new MyQueue();
mq.add(nodes[x][y]);
while (!mq.isEmpty()) {
Node no1 = mq.pop();
if (no1.value == 3) {
return no1;
}
for (int i = 0; i < dir.length; i++) {
int a = no1.x + dir[i][0];
int b = no1.y + dir[i][1];
// 越界
if (a < 0 || b < 0 || a >= n || b >= m) {
continue;
}
// 遇到障碍物
if (nodes[a][b].value == 0) {
continue;
}
// 时间不够
if (no1.time - 1 == 0) {
continue;
}
/*
* 移动到同一个结点,
* 那么这次的时间应该要比上次的时间更长。
* 数据初始化的时候,应该吧时间改为-1,
* 这样就可以正常移动了。
*/
if (nodes[a][b].time >= no1.time - 1) {
continue;
}
/*
* 遇到时间重置装置,
* 不允许下次再走这个地方。
*/
if (nodes[a][b].value == 4) {
nodes[a][b].value = 0;
nodes[a][b].set(a, b, 6, no1.step + 1);
mq.add(nodes[a][b]);
continue;
}
/*
* 添加元素到队列中。
*/
nodes[a][b].set(a, b, no1.time - 1, no1.step + 1);
mq.add(nodes[a][b]);
}
}
return null;
}
}
class Node {
int value;
int x;
int y;
int time;
int step;
public Node(int value, int x, int y, int time, int step) {
this.value = value;
this.x = x;
this.y = y;
this.time = time;
this.step = step;
}
public void set(int x, int y, int time, int step) {
this.x = x;
this.y = y;
this.time = time;
this.step = step;
}
@Override
public String toString() {
return "Node [value=" + value + ", x=" + x + ", y=" + y + ", time="
+ time + ", step=" + step + "]";
}
}
/*
* 使用ArrayList容器,
* 这个比Object数组好用一些。
* 已经测试队列为空。
*/
class MyQueue {
ArrayList<Node> al = new ArrayList<Node>();
int index;
public MyQueue() {
index = 0;
}
public void add(Node no) {
al.add(no);
index++;
}
public Node pop() {
if (al.isEmpty()) {
return null;
}
Node nod = al.remove(0);
index--;
return nod;
}
public boolean isEmpty() {
return al.isEmpty();
}
}
Nightmare
恶梦
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8533 Accepted Submission(s): 4088
Problem Description
Ignatius had a nightmare last night. He found himself in a labyrinth with a time bomb on him.
Ignatius昨天晚上做了一个噩梦。他发现自己身上有一颗炸弹,且自己在迷宫中。
The labyrinth has an exit, Ignatius should get out of the labyrinth before the bomb explodes.
迷宫有一个出口,在炸弹爆炸前Ignatius因该走出迷宫。
The initial exploding time of the bomb is set to 6 minutes.
定时炸弹初始爆炸时间是6秒。
To prevent the bomb from exploding by shake, Ignatius had to move slowly,
为了不使移动过程中炸弹爆炸,Ignatius必须小心的行动,
that is to move from one area to the nearest area(that is, if Ignatius stands on (x,y) now,
假如Ignatius处于(x,y)坐标处,当他要移动到附近的地方时,
he could only on (x+1,y), (x-1,y), (x,y+1), or (x,y-1) in the next minute) takes him 1 minute.
他只能每秒移动到(x+1,y), (x-1,y), (x,y+1), or (x,y-1) 这四点的某一处。
Some area in the labyrinth contains a Bomb-Reset-Equipment.
迷宫的一些地方有炸弹。
They could reset the exploding time to 6 minutes.
他们炸弹的时间是6秒。
Given the layout of the labyrinth and Ignatius' start position,
他们炸弹的时间是6秒。
Given the layout of the labyrinth and Ignatius' start position,
给出迷宫的布局和一个Ignatius的起点,
please tell Ignatius whether he could get out of the labyrinth,
请写一个程序告诉Ignatius他是否可以走出迷宫,
if he could, output the minimum time that he has to use to find the exit of the labyrinth, else output -1.
如果他可以,请输出他走出迷宫的时间,否则输出-1;
Here are some rules:
Here are some rules:
游戏规则如下:
1. We can assume the labyrinth is a 2 array.
1. We can assume the labyrinth is a 2 array.
我们可以认为迷宫是一个2维数组。
2. Each minute, Ignatius could only get to one of the nearest area, and he should not walk out of the border, of course he could not walk on a wall, too.
2. Each minute, Ignatius could only get to one of the nearest area, and he should not walk out of the border, of course he could not walk on a wall, too.
每一秒Ignatius只能移动一步,且是临近的位置,他不能走出边界,当然他也不能再墙上走。
3. If Ignatius get to the exit when the exploding time turns to 0, he can't get out of the labyrinth.
3. If Ignatius get to the exit when the exploding time turns to 0, he can't get out of the labyrinth.
当炸弹爆炸前,如果Ignatius没有走出了迷宫,那么Ignatius也就不能走出迷宫。
4. If Ignatius get to the area which contains Bomb-Rest-Equipment when the exploding time turns to 0, he can't use the equipment to reset the bomb.
4. If Ignatius get to the area which contains Bomb-Rest-Equipment when the exploding time turns to 0, he can't use the equipment to reset the bomb.
当炸弹为0时,如果Ignatius走到有重置炸弹的地方,这时他不能重新设定炸弹爆炸的时间,可以说他死定了。
5. A Bomb-Reset-Equipment can be used as many times as you wish, if it is needed, Ignatius can get to any areas in the labyrinth as many times as you wish.
5. A Bomb-Reset-Equipment can be used as many times as you wish, if it is needed, Ignatius can get to any areas in the labyrinth as many times as you wish.
如果可以任意使用炸弹重置装置,Ignatius可以任意调节时间。
6. The time to reset the exploding time can be ignore, in other words,
6. The time to reset the exploding time can be ignore, in other words,
换句话说,可以忽略时间重置爆炸时间,
if Ignatius get to an area which contain Bomb-Rest-Equipment, and the exploding time is larger than 0, the exploding time would be reset to 6.
如果Ignatius走到一个重置炸弹的区域,炸弹的时间大于0,那么爆炸的时间将重置为6。
Input
The input contains several test cases.
输入语句包含多组测试事件。
The first line of the input is a single integer T which is the number of test cases.
输入的第一行有一个整数T,他表示测试事件的个数。
T test cases follow.
接下来输入T个测试数据。
Each test case starts with two integers N and M(1<=N,Mm=8) which indicate the size of the labyrinth.
Each test case starts with two integers N and M(1<=N,Mm=8) which indicate the size of the labyrinth.
每一个测试事件的起始行包含两个整数N和M(1<=n,m<=8),表示迷宫的大小。
Then N lines follow, each line contains M integers.
接下来再输入N行数据,每一行都有M个整数。
The array indicates the layout of the labyrinth.
数组表示迷宫的布局。
There are five integers which indicate the different type of area in the labyrinth:
There are five integers which indicate the different type of area in the labyrinth:
在迷宫中有五种数据,分别表示如下:
0: The area is a wall, Ignatius should not walk on it.
0: The area is a wall, Ignatius should not walk on it.
0表示墙,Ignatius不能在上面移动。
1: The area contains nothing, Ignatius can walk on it.
1: The area contains nothing, Ignatius can walk on it.
1表示什么东西也没有,Ignatius可以任意移动。
2: Ignatius' start position, Ignatius starts his escape from this position.
2: Ignatius' start position, Ignatius starts his escape from this position.
2表示Ignatius的起始位置,也是Ignatius的逃亡起始点。
3: The exit of the labyrinth, Ignatius' target position.
3: The exit of the labyrinth, Ignatius' target position.
3表示迷宫的出口,Ignatius的目标位置。
4: The area contains a Bomb-Reset-Equipment, Ignatius can delay the exploding time by walking to these areas.
4: The area contains a Bomb-Reset-Equipment, Ignatius can delay the exploding time by walking to these areas.
4表示一颗定时炸弹时间重置器,当Ignatius走在上面后可以重新设置爆炸时间。
Output
For each test case, if Ignatius can get out of the labyrinth, you should output the minimum time he needs, else you should just output -1.
对于每一个测试事件,如果Ignatius可以走出迷宫,你应该输出他走出迷宫的时间,否则输出-1;
Sample Input
3 3 3 2 1 1 1 1 0 1 1 3 4 8 2 1 1 0 1 1 1 0 1 0 4 1 1 0 4 1 1 0 0 0 0 0 0 1 1 1 1 4 1 1 1 3 5 8 1 2 1 1 1 1 1 4 1 0 0 0 1 0 0 1 1 4 1 0 1 1 0 1 1 0 0 0 0 3 0 1 1 1 4 1 1 1 1 1
Sample Output
4 -1 13
Author
Ignatius.L