P1090 合并果子
链接:https://www.luogu.org/problemnew/show/P1090
题意:就是用最小的力气把所有的果子堆合并在一起,输出这个力气。
题解:看到题目很容易想到优先队列,按照从小到大的顺序,以此取出两个,再记录所用的力气,然后把合并之后的果子堆,再压入优先队列,按照上述方法接着操作。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
priority_queue<int, vector<int>, greater<int> >q;//优先队列按照从小到大的顺序
int main(){
int n, t, i;
cin>>n;
for(i = 0; i < n; i++){
cin>>t;
q.push(t);
}
long long sum = 0;
while(!q.empty()){
int a = q.top();
q.pop();
int b = q.top();
q.pop();
sum += a + b;//记录力气的花费
if(!q.empty()){
q.push(a+b);
}
}
cout<<sum<<endl;
return 0;
}
P1181 数列分段Section I
链接:https://www.luogu.org/problemnew/show/P1181
题意:本题就是一段长度为N的数组,按照几个数的和小于等于m,问最小可以分成几段
题解:遍历一遍,用k记录几个数的和,sum记录可以分的段数,如果k大于m那么k=此时的数,最后输出结果。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int main(){
int n, m;
cin>>n>>m;
int i, t, sum = 0, k = 0;
for(i = 0; i < n; i++){//遍历
cin>>t;
if(k + t <= m){//如果总数小于m
k += t;
}
else {
k = t;
sum ++;
}
}
cout<<sum+1<<endl;//最后一个没有记录所以需要+1;
return 0;
}
P1208 [USACO1.3]混合牛奶 Mixing Milk
题意:已知需要牛奶的吨数,求出购买牛奶的最小花费。
题解:就是把牛奶的价格排序,按照从小到打得顺序,遍历一遍,如果牛奶的吨数小于等于需求接着往下遍历,此外还需记录已经购买多少牛奶,还有花费的金额。直到牛奶的吨数大于需求的,用需要的牛奶吨数减去已经购买的,乘以此时的价格,然后加上之前的金额,这就是最小的花费。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
struct milk{
int kind, val;
}M[5005];
bool cmp(milk A, milk B){//按照从小到大的顺序
return A.val < B.val;
}
int main(){
int n, m, k = 0, i;
cin>>n>>m;
long long sum = 0;
for(i = 0; i < m; i++){
cin>>M[i].val>>M[i].kind;
}
sort(M, M + m,cmp);//排序
for(i = 0; i < m; i++){
if(k + M[i].kind <= n){//如果此时购买牛奶的数量小于需求量
sum += M[i].kind*M[i].val;
k += M[i].kind;
}
else{//此时牛奶的数量大于需求量
sum += ((n - k) * M[i].val);
break;//这个是非常的有必要,如果没有回接着遍历会是总金额偏大
}
}
cout<<sum<<endl;
return 0;
}
P1223 排队接水
链接:https://www.luogu.org/problemnew/show/P1223
题意:就是一群人排队接水,问最平均等待时间,以及如何排序是使这个等待时间最小。
题解:只有接水时间最小的人在前面接水,所以把接水时间按照从小到大的顺序,接水是均等待时间最小,排在自己前面所有人接水时间之和就是此人等待时间,再把所有人等待时间加在一起除以总人数就是平均等待时间。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
struct water{
int order, time;//order记顺序,time记录接水的时间
}w[1005];
bool cmp(water A, water B){
return A.time < B.time;
}
int main(){
int n, i;
cin>>n;
for(i = 0; i < n; i++){
cin>>w[i].time;
w[i].order = i + 1;
}
sort(w, w + n, cmp);
long long ans = 0, sum = w[i].time;
for(i = 1; i < n; i++){
sum += w[i-1].time;
ans += sum;
}
for(i = 0; i < n; i++){
cout<<w[i].order<<' ';
}
cout<<endl;
double t = (ans*(1.0)) / n;
printf("%.2lf\n", t);
return 0;
}
P1094 纪念品分组
链接:https://www.luogu.org/problemnew/show/P1094
题意:就是是两个人礼物价值之和小于n,最少有多少种划分
题解:把价值大于n/2的划分在一组,用数组a来记录,把价值小于n/2用数组b来记录,a按照从大到小的顺序,b按照从小到大的顺序,然后开始遍历,用i来记录a的位置,用j来记录b的位置,如果a[i]+b[j] <= n, 化分个数m++,直到i<a的长度&&j<b的长度,循环结束。最后m需要加上a中剩余的,加上b中剩余的除以2向上取整,这就是最终结果。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int a[30003], b[30003];
bool cmp(int a, int b){
return a > b;
}
int main(){
int n, m;
cin>>n>>m;
int i, j, t, cn = 0, cnt = 0;
for(i = 0; i < m; i++){
cin>>t;
if(t > n/2)a[cn++] = t;
else b[cnt++] = t;
}
sort(a,a + cn, cmp);
sort(b, b + cnt);
int ans = 0;
i = 0, j = 0;
while(i < cn && j < cnt){
if(a[i] + b[j] <= n){
ans++;
i++;
j++;
}
else {
i++;
}
}
int k = cnt - j;
if(k % 2 == 0)k /= 2;
else k = k / 2 + 1;
ans += cn - j + k;
cout<<ans<<endl;
return 0;
}
P1803 凌乱的yyy / 线段覆盖
链接:https://www.luogu.org/problemnew/show/P1803
题意:就是yyy打比赛,已知每场比赛的开始时间和结束时间,
题解:按照结束的时间按照从小到大的顺序,如果开始的此时开始的时间大于之前结束的时间比赛数量+1.
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
pair<int, int>p[1000005];
typedef pair<int, int>P;
int cmp(P a, P b){
return a.second < b.second;
}
int main(){
int n, i, ans = 0;
cin>>n;
for(i = 0; i < n; i++){
cin>>p[i].first>>p[i].second;
}
sort(p, p + n, cmp);
int t = p[0].second;
for(i = 1; i < n; i++){
if(p[i].first >= t){
ans++;
t = p[i].second;
}
}
cout<<ans+1<<endl;//第一场比赛没有算进去,所以需要+1;
return 0;
}
P1031 均分纸牌
链接:https://www.luogu.org/problemnew/show/P1031
题意:就是进行最少的操作是所有人的纸牌数相等,两端的人只能向中间传送纸牌。
题解:求出平均值,然后所有的数据减去平均值,然后遍历一遍,按照从左向右的顺序。
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int a[10005];
int main(){
int n, i, cn = 0, ave = 0;
cin>>n;
for(i = 0; i < n; i++){
cin>>a[i];
ave += a[i];
}
ave /= n;
for(i = 0; i < n; i++)a[i] -= ave;
for(i = 0; i < n; i++){
if(a[i] == 0)continue;
a[i+1] += a[i];
cn++;
}
cout<<cn<<endl;
return 0;
}