暑假算法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;
}
};
第五题
题目大意:有一个十进制且不带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;
}
}
}