暑假算法7.11,Day10

暑假算法7.11,Day10

优先队列

我也是第一次学优先队列,有什么问题多多包涵

首先讲一下C++中的优先队列的排序方式

priority_queue<Type, Container, Functional>

Type为数据类型, Container为保存数据的容器,Functional为元素比较方式。

如果不写后两个参数,那么容器默认用的是vector,比较方式默认用operator<,也就是优先队列是大顶堆,队头元素最大。

C++中默认的是优先输出大数据

priority_queue<int> p;

如果需要优先输出小数据的话就采用

priority_queue<int, vector<int>, greater<int> > p;

还有一种自定义的方法,我也不是很会,这里就不提了。

接下来就一写下面的题目了。

第一题

最后一块石头的重量

//Java
class Solution {
    public int lastStoneWeight(int[] stones) {
        PriorityQueue<Integer> dl=new PriorityQueue<Integer>((a,b)->b-a);
        //利用Lamda 表达式改变PriorityQueue的排序方式,倒序!
        for (int stone : stones) {
            dl.offer(stone);
        }
        while (dl.size() > 1) {
            int a = dl.poll();
            int b = dl.poll();
            if (a > b) {
                dl.offer(a - b);
            }
        }
        return dl.isEmpty() ? 0 : dl.poll();
    }
}

//C++
class Solution {
public:
    int lastStoneWeight(vector<int>& stones) {
        priority_queue<int>p;
        for(int i=0;i<stones.size();i++){
            p.push(stones[i]);
        }
        while(p.size()>1){
            int a=p.top();
            p.pop();
            int b=p.top();
            p.pop();
            if(a>b){
                p.push(a-b);
            }
        }
        return p.empty()?0:p.top();
    }
};

请添加图片描述

第二题

装满杯子需要的最短总时长

//Java
class Solution {
    public int fillCups(int[] amount) {
        PriorityQueue<Integer> dl=new PriorityQueue<Integer>((a,b)->a-b);
        for(int s:amount){
            dl.offer(s);
        }
        int a=0,b=0,c=0;
        while(dl.size()>1){
            a=dl.poll();
            b=dl.poll();
            c=dl.poll();
            if(a+b<c){
                return c;
            }
        }
        int t = a + b - c;
        return (t + 1) / 2 + c;
    }
}

//C++
class Solution {
public:
    int fillCups(vector<int>& amount) {
        priority_queue<int, vector<int>, greater<int> > p;
        for(int i=0;i<amount.size();i++){
            p.push(amount[i]);
        }
        int a=0,b=0,c=0;
        while(p.size()>1){
            a=p.top();
            p.pop();
            b=p.top();
            p.pop();
            c=p.top();
            p.pop();
            if(a+b<=c){
                return c;
            }
        }
        int d=a+b-c;
        return (d+1)/2+c;
    }
};

请添加图片描述

第三题

移除石子的最大得分

//Java
class Solution {
    public int maximumScore(int a, int b, int c) {
        PriorityQueue<Integer>p=new PriorityQueue<Integer>((x,y)->x-y);
        int[] arr = new int[] { a, b, c };
        for(int z:arr){
            p.offer(z);
        }
        int m=0,n=0,k=0;
        while(p.size()>1){
            m=p.poll();
            n=p.poll();
            k=p.poll();
            if(m+n<=k){
                return m+n;
            }
        }
        return (m+n+k)/2;
    }
}

//C++
class Solution {
public:
    int maximumScore(int a, int b, int c) {
        vector<int> arr(3);
        arr[0] = a;arr[1]=b;arr[2] =c;
        sort(arr.begin(),arr.end());
		a = arr[0];
		b = arr[1];
		c = arr[2];
		if (a + b <= c) {
			return a + b;
		} else {
			return (a + b + c) / 2;
		}
    }
};

请添加图片描述

第四题

最低加油次数

//C++
class Solution {
public:
    int minRefuelStops(int target, int startFuel, vector<vector<int>>& stations) {
        //默认是大顶堆
        priority_queue<int> q;
        //target 也作为加油站加入
        stations.push_back({target, 0});
        //start 记录前一个出发点位置, res 记录加油次数
        int start = 0, res = 0;
        for(auto station : stations) {
            startFuel -= station[0] - start;
            //判断是否需要加油
            while(startFuel < 0 && !q.empty()) {
                startFuel += q.top();
                q.pop();
                res++;
            }
            //即使前面所有加油站都加油也到达不了
            if(startFuel < 0) return -1;
            //达到加油站,加入优先队列,为后面做准备
            q.push(station[1]);
            start = station[0];
        }
        return res;
    }
};

请添加图片描述

第五题

Digit Minimization

题目大意:有一个十进制且不带0的整数n,两个同学a和b玩游戏,a先开始,a每次必须交换不同位置的任意两位整数,b总是每次删除数字的最后一位,也就是个位,当只有一个数字时游戏结束,假设a发挥最佳,请你找到a同学最后能得到的最小整数。

这个题目是个思维题,想到了就很简单,就是**要求一个数中哪一位最小**。

测试样例只有两位数和两位以上时情况是不一样的。

因为a每次都必须交换位置,所以只有两位数时,直接取余就得到解。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin >> t;
    while (t -- )
    {
        int n;
        cin >> n;
        int mmin= 10;
        if (n < 100)
        {
            cout << n % 10 << endl;
        }
        else
        {
            while (n)
            {
                int tmp = n % 10;
                mmin = min(mmin, tmp);
                n /= 10;
            }
            cout << mmin << endl;
        }
    }
}

请添加图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值