在看着道题目之前就听说过要用到优先级队列,简单的看了一下下,学长写个例子给我,就这样A了这道题目。所以再看这道题目之前先来看看优先级队列。
优先级队列
如果我们给每个元素都分配一个数字来标记其优先级,不妨设较小的数字具有较高的优先级,这样我们就可以在一个集合中访问优先级最高的元素并对其进行查找和删除操作了。这样,我们就引入了优先级队列 这种数据结构。 优先级队列(priority queue) 是0个或多个元素的集合,每个元素都有一个优先权,对优先级队列执行的操作有(1)查找(2)插入一个新元素 (3)删除 一般情况下,查找操作用来搜索优先权最大的元素,删除操作用来删除该元素 。对于优先权相同的元素,可按先进先出次序处理或按任意优先权进行。
ps:这是百度上面的定义,简单的理解着说,就是给一个队列的元素找到一种排列方式(加上权值什么的),让其中的元素按照你想要的顺序弹出。还没有自己完整的写过这样的结构,只是单单的用了STL中的priority_queue。
因为理解的不多,所以简单列出它的函数~~
STL之priority_queue(优先级队列):
头文件:#include <queue>
empty() 如果优先队列为空,则返回真
pop() 删除第一个元素
push() 加入一个元素
size() 返回优先队列中拥有的元素的个数
top() 返回优先队列中有最高优先级的元素
另外,需要自己定义优先级类型~也就是在结构体中加入一个函数,让元素排好队,重载运算符~
例子:
#include <stdio.h>
#include <queue>
using namespace std;
struct NODE
{
int x;
int y;
friend bool operator<(const NODE a, const NODE b)
{
return a.x > b.x;
}
};
int main()
{
priority_queue<NODE> q;
NODE temp;
temp.x = 3;
temp.y = 6;
q.push(temp);
temp.x = 5;
temp.y = 9;
q.push(temp);
temp.x = 4;
temp.y = 1;
q.push(temp);
temp.x = 2;
temp.y = 7;
q.push(temp);
while(!q.empty())
{
printf("%d %d\n", q.top().x, q.top().y);
q.pop();
}
}
现在到了题目喽~
坦克大战
-
描述
-
Many of us had played the game "Battle city" in our childhood, and some people (like me) even often play it on computer now.
What we are discussing is a simple edition of this game. Given a map that consists of empty spaces, rivers, steel walls and brick walls only. Your task is to get a bonus as soon as possible suppose that no enemies will disturb you (See the following picture).
Your tank can't move through rivers or walls, but it can destroy brick walls by shooting. A brick wall will be turned into empty spaces when you hit it, however, if your shot hit a steel wall, there will be no damage to the wall. In each of your turns, you can choose to move to a neighboring (4 directions, not 8) empty space, or shoot in one of the four directions without a move. The shot will go ahead in that direction, until it go out of the map or hit a wall. If the shot hits a brick wall, the wall will disappear (i.e., in this turn). Well, given the description of a map, the positions of your tank and the target, how many turns will you take at least to arrive there?-
输入
-
The input consists of several test cases. The first line of each test case contains two integers M and N (2 <= M, N <= 300). Each of the following M lines contains N uppercase letters, each of which is one of 'Y' (you), 'T' (target), 'S' (steel wall), 'B' (brick wall), 'R' (river) and 'E' (empty space). Both 'Y' and 'T' appear only once. A test case of M = N = 0 indicates the end of input, and should not be processed.
输出
-
For each test case, please output the turns you take at least in a separate line. If you can't arrive at the target, output "-1" instead.
样例输入
-
3 4 YBEB EERE SSTE 0 0
样例输出
-
8
-
The input consists of several test cases. The first line of each test case contains two integers M and N (2 <= M, N <= 300). Each of the following M lines contains N uppercase letters, each of which is one of 'Y' (you), 'T' (target), 'S' (steel wall), 'B' (brick wall), 'R' (river) and 'E' (empty space). Both 'Y' and 'T' appear only once. A test case of M = N = 0 indicates the end of input, and should not be processed.
就是坦克能否到达目的T,其中铁墙和小河是不能走的,砖墙可以打碎,但是每走一次砖墙步数加2,空地不用说了,可以走,每次加1。如果能够到达目的地,输出步数,不能就输出-1 。
嗯~详见代码
#include <iostream>
#include <stdio.h>
#include <queue>
#include <string.h>
#define N 301
using namespace std;
struct node
{
int x;
int y;
int step;
friend bool operator<(const node &t1, const node &t2) //优先级队列的排列条件
{
return t1.step>t2.step;//因为走空地和走砖墙的步数不同,所以可以让其按照步数多少来排列~肯定是优先选择空地了
}
};
int S_x, S_y;
char map[N][N];
int n, m;
const int flag[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};//标记数组~向上下左右四个方向。。
int bfs()
{
priority_queue <node> Q;
node start, p;
start.x = S_x;
start.y = S_y;
start.step = 0;
Q.push(start);
while(!Q.empty())
{
p = Q.top();
Q.pop();
int i;
node q;
for(i=0; i<4; i++)
{
q.x = p.x + flag[i][0];
q.y = p.y + flag[i][1];
q.step = 0; //注意把步数设成0
if(q.x>=0 && q.x<n && q.y>=0 && q.y<m && map[q.x][q.y]!='S' && map[q.x][q.y]!='R')
{
if(map[q.x][q.y] == 'T')
{
return p.step + 1;
}
else if(map[q.x][q.y] == 'E')
{
q.step = p.step + 1;
Q.push(q);
map[q.x][q.y] = 'S';
}
else if(map[q.x][q.y] == 'B')
{
q.step = p.step + 2;
Q.push(q);
map[q.x][q.y] = 'S';
}
}
}
}
return -1;
}
int main()
{
while(scanf("%d%d", &n, &m) && (n+m))
{
getchar();
int i, j;
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
scanf("%c", &map[i][j]);
if(map[i][j] == 'Y') //记录下开始~
{
S_x = i;
S_y = j;
}
}
getchar();
}
printf("%d\n", bfs());
}
return 0;
}
下一道题目:基本都是一样的~
背景
可是……停电了……
冰淇淋们躺在Ice-cream home的冰柜里,慢慢地……慢慢地……融化…………
你说,她能赶在冰淇淋融化完之前赶到Ice-cream home去吗?
描述
输入格式
输出格式
测试样例1
输入
11
10
8
......s...
..........
#ooooooo.o
#.........
#.........
#.........
#.....m...
#.........
输出
10
不解释了~贴代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
struct node
{
int x;
int y;
int time;
friend bool operator<(const node &t1, const node &t2)
{
return t1.time > t2.time;
}
};
const int flag[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
char town[26][26];
int s_x, s_y;
int X, Y;
int t;
int bfs()
{
priority_queue <node> Q;
node start, p;
start.x = s_x;
start.y = s_y;
start.time = 0;
Q.push(start);
town[start.x][start.y] = 'o';
while(!Q.empty())
{
p = Q.top();
Q.pop();
node q;
int i;
for(i=0; i<4; i++)
{
q.x = p.x + flag[i][0];
q.y = p.y + flag[i][1];
q.time = 0;
if(q.x>=0 && q.x<Y && q.y>=0 && q.y<X && town[q.x][q.y]!='o')
{
if(town[q.x][q.y] == 'm')
{
return p.time + 1;
}
else if(town[q.x][q.y] == '.')
{
q.time = p.time + 1;
Q.push(q);
town[q.x][q.y] = 'o';
}
else if(town[q.x][q.y] == '#')
{
q.time = p.time + 2;
Q.push(q);
town[q.x][q.y] = 'o';
}
}
}
}
return -1;
}
int main()
{
scanf("%d%d%d", &t, &X, &Y); //X:长 列 Y:宽 行
int i, j;
for(i=0; i<Y; i++)
{
scanf("%s", town[i]);
}
for(i=0; i<Y; i++)
{
for(j=0; j<X; j++)
{
if(town[i][j] == 's')
{
s_x = i;
s_y = j;
}
}
}
int c_t = 0;
c_t = bfs();
if(c_t != -1 && c_t < t)
{
printf("%d\n", c_t);
}
else
printf("55555\n");
return 0;
}