【题目来源】
https://www.luogu.com.cn/problem/B4452
【题目描述】
小 A 有 M 元预算。商店有 N 个商品,每个商品有商品名 S、价格 P 和优先级 V 三种属性,其中 V 为正整数,且V 越小代表商品的优先级越高。
小 A 的购物策略为:
(1)总是优先买优先级最高的东西;
(2)如果有多个最高优先级商品,购买价格最低的;
(3)如果有多个优先级最高且价格最低的商品,购买商品名字典序最小的。
小 A 想知道能购买哪些商品。
【输入格式】
第一行两个正整数 M,N,代表预算和商品数。
之后 N 行,每行一个商品,依次为 Si Pi Vi,代表第 i 个商品的商品名、价格、优先级。
数据保证不存在两个名字相同的商品。
【输出格式】
按照字典序从小到大的顺序,输出所有购买商品的商品名。
【输入样例】
20 4
apple 6 8
bus 15 1
cab 1 10
water 4 8
【输出样例】
bus
cab
water
【数据范围】
对于所有测试点,保证 1≤∣Si∣≤10,1≤M,Pi≤10^5,1≤N≤10^3,1≤Vi≤10。商品名仅由小写字母组成且不存在两个相同的商品名。
【算法分析】
● 按结构体某一字段对结构体数组进行排序:https://blog.csdn.net/hnjzsyjyj/article/details/120184972
● 本题需进行两次排序。
【算法代码一:string】
#include <bits/stdc++.h> using namespace std; const int maxn=1e3+5; struct Goods { string s; int p; int v; } t[maxn]; bool cmp(Goods x,Goods y) { if(x.v!=y.v) return x.v<y.v; else if(x.p!=y.p) return x.p<y.p; else return x.s<y.s; } int main() { int m,n; cin>>m>>n; for(int i=1; i<=n; i++) { cin>>t[i].s>>t[i].p>>t[i].v; } sort(t+1,t+1+n,cmp); string v[maxn]; int cnt=0; for(int i=1; i<=n; i++) { if(m>=t[i].p) { m-=t[i].p; v[++cnt]=t[i].s; } } sort(v+1,v+1+cnt); for(int i=1; i<=cnt; i++) { cout<<v[i]<<endl; } return 0; } /* in: 20 4 apple 6 8 bus 15 1 cab 1 10 water 4 8 out: bus cab water */【算法代码二:vector】
#include <bits/stdc++.h> using namespace std; const int maxn=1e3+5; struct Goods { string s; int p; int v; } t[maxn]; bool cmp(Goods x,Goods y) { if(x.v!=y.v) return x.v<y.v; else if(x.p!=y.p) return x.p<y.p; else return x.s<y.s; } int main() { int m,n; cin>>m>>n; for(int i=1; i<=n; i++) { cin>>t[i].s>>t[i].p>>t[i].v; } sort(t+1,t+1+n,cmp); vector<string> v; for(int i=1; i<=n; i++) { if(m>=t[i].p) { m-=t[i].p; v.push_back(t[i].s); } } sort(v.begin(),v.end()); for(auto x:v) cout<<x<<endl; return 0; } /* in: 20 4 apple 6 8 bus 15 1 cab 1 10 water 4 8 out: bus cab water */
【参考文献】
https://mp.weixin.qq.com/s/sWxpISqwh2OfFGjqVIn1PQ
https://blog.csdn.net/jht0105/article/details/135998672
https://blog.csdn.net/m0_69389639/article/details/146261239