优先队列

问题 K: 育英晨跑

题目描述
在育英,大家最头疼的事情就是晨跑了,因为每天早上大家都要被迫从温暖的被窝爬起来去晨跑令人非常不爽。
育英的晨跑是使用一款APP来规定晨跑路线,我们可以把育英校园看作一个n * m的二维矩阵。LZY的起点在左上角(0,0),而APP规定的终点为右下角(n - 1,m - 1) 。
LZY跑到每个点的用时都不一样,现在LZY为了偷懒,想找一条耗时最短的捷径,你能帮帮他吗?
输入
测试样例由多组测试数据组成。每组测试数据第一行输入两个正整数n , m ( 1 <= n,m <= 100)
接下来输入n * m 个数字 ,每个数字不超过 500
输出
输出LZY从起点跑到终点的最短用时
样例输入
3 3
3 2 1
3 2 1
3 2 1
样例输出
8

AC代码:

#include<bits/stdc++.h>
#include<queue>
using namespace std;
int n,m;
int s[105][105];
bool vis[105][105];
int dir[4][2]={0,1,1,0,0,-1,-1,0};
struct node{
    int x,y,num;
};
struct cmp{
    bool operator()(node a,node b){
        return a.num>b.num;
    }
};
priority_queue<node,vector<node>,cmp> qu;
bool check(int x,int y){
    if(x<0||x>=n||y<0||y>=m)
        return false;
    return true;
}
int bfs(){
    node cur,nex;
    while(!qu.empty()){
        cur=qu.top();
        qu.pop();
        if(cur.x==n-1&&cur.y==m-1){
            return cur.num;
        }
        for(int i=0;i<4;i++){
            nex.x=cur.x+dir[i][0];
            nex.y=cur.y+dir[i][1];
            nex.num=s[nex.x][nex.y]+cur.num;
            if(check(nex.x,nex.y)&&vis[nex.x][nex.y]==false){
                vis[nex.x][nex.y]=true;
                qu.push(nex);
            }
        }
    }
}
int main(){
    while(cin>>n>>m){
        while(!qu.empty()){
            qu.pop();
        }
        memset(vis,false,sizeof(vis));
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                cin>>s[i][j];
            }
        }
        node cur;
        cur.x=0;
        cur.y=0;
        cur.num=s[0][0];
        qu.push(cur);
        cout<<bfs()<<endl;
    }
    return 0;
}

问题 H: LZY碎大石

题目描述
由于LZY半夜3点50分吵醒了营长,营长很生气,让他去工地体验一下搬砖生活。包工头给了LZY一个任务,他给了LZY一大堆石头,让LZY每次挑出两块最重的石头,然后将它们一起粉碎。

假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:

如果 x == y,那么两块石头都会被完全粉碎;
如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。

最后,最多只会剩下一块石头。输出此石头的重量。如果没有石头剩下,就输出 0。

输入
测试样例由多组测试数据组成。每组测试数据第一行输入一个正整数n ( 1 <= n <= 10000)代表包工头给LZY的石头总数,
第二行输入n个正整数ni ( 1 <= ni <= 10000 )代表每块石头的重量。
输出
如果LZY最后只剩下了一块石头,则输出最后块石头的重量。否则输出0
样例输入
6
2 7 4 1 8 1
样例输出
1

AC代码:

#include<bits/stdc++.h>
using namespace std;
priority_queue<int,vector<int>,less<int> > qu;
int bfs(){
    int cur,nex;
    while(!qu.empty()){
        int len=qu.size();
        if(len<2){
            return qu.top();
        }
        cur=qu.top();
        qu.pop();
        nex=qu.top();
        qu.pop();
        int ans=abs(cur-nex);
        if(ans) qu.push(ans);
    }
    return 0;
} 
int main(){
    int n;
    while(cin>>n){
        while(!qu.empty()){
            qu.pop();
        }
        while(n--){
            int m;
            cin>>m;
            qu.push(m);
        }
        cout<<bfs()<<endl; 
    }
    return 0;
}

考点:优先队列
//升序队列
priority_queue <int,vector,greater > q;
//降序队列
priority_queue <int,vector,less >q;

top 访问队头元素
empty 队列是否为空
size 返回队列内元素个数
push 插入元素到队尾 (并排序)
emplace 原地构造一个元素并插入队列
pop 弹出队头元素
swap 交换内容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值