nyoj284坦克大战 and tyvj p1117拯救冰淇淋

5 篇文章 0 订阅

       在看着道题目之前就听说过要用到优先级队列,简单的看了一下下,学长写个例子给我,就这样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();
    }
}
现在到了题目喽~

坦克大战

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
描述
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
广搜的题目,大概解释一下~~ps:其实我偷个小懒没仔细看题目

就是坦克能否到达目的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;
}

下一道题目:基本都是一样的~


P1117 拯救ice-cream
时间: 1000ms / 空间: 131072KiB / Java类名: Main

背景

天好热……Tina顶着那炎炎的烈日,向Ice-cream home走去……
可是……停电了……
冰淇淋们躺在Ice-cream home的冰柜里,慢慢地……慢慢地……融化…………
你说,她能赶在冰淇淋融化完之前赶到Ice-cream home去吗?

描述

给你一张坐标图,s为Tina的初始位置,m为Ice-cream home的位置,‘.’为路面,Tina在上面,每单位时间可以移动一格;‘#’为草地,Tina在上面,每两单位时间可以移动一格(建议不要模仿—毕竟Tina还小);‘o’是障碍物,Tina不能在它上面行动。也就是说,Tina只能在路面或草地上行走,必须绕过障碍物,并到达冰淇淋店。但是…………不保证到达时,冰淇淋还未融化,所以……就请聪明的你……选择最佳的方案啦…………如果,Tina到的时候,冰淇淋已经融化完了,那她可是会哭的。

输入格式

依次输入冰淇淋的融化时间t(0<t<1000),坐标图的长x,宽y(5<=x,y<=25){太长打起来好累……},和整张坐标图。

输出格式

判断按照最优方案是否可以赶在冰淇淋融化之前到达冰淇淋店(注:当T=最优方案所用时间,则判断为未赶到),如赶到,输出所用时间;如未赶到,输出Tina的哭声——“55555”(不包括引号)。

测试样例1

输入

11 
10 

......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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值