【题目描述】
一实食堂有 个菜,第 个菜的价格是 [] 元钱,现有 个同学,第 个同学的饭卡有[]元钱。
问第 个同学最多能打多少个菜?
【输入】
第 1 行 1 个整数
第 2 行 个整数 []...[]
第 3 行 1 个整数
第 4 行 个整数 []...[]
【输出】
输出 行, 第 行表示第 个同学最多能打多少菜。
【输入输出样例】
Input
5
300 100 400 100 500
3
500 250 40
Output
3
2
0
【数据范围】
【题解】
讲两种做法。
【做法一、传统贪心】
首先,对 数组进行排序
然后,遍历每一个学生所拥有的钱,并在内遍历 数组。设立一个计数变量 ,用来记录已经打的菜品数量,并设立一个变量 ,用来记录已打菜品所花的钱,一旦 ,就输出 。
代码实现如下:
#include<bits/stdc++.h>
using namespace std;
int n,q;
int c[100100],x[100100],cnt,ans;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for(int i = 1;i <= n;i++){
cin >> c[i];
}
cin >> q;
for(int i = 1;i <= q;i++){
cin >> x[i];
}
sort(c + 1,c + 1 + n);
for(int i = 1;i <= q;i++){
cnt = 0;
ans = 0;
bool flag = true;
for(int j = 1;j <= n;j++){
cnt += c[j];
if(cnt > x[i]){
cout << ans << "\n";
flag = false;
break;
}
else if(cnt == x[i]){
ans++;
cout << ans << "\n";
flag = false;
break;
}
ans++;
}
if(flag == true){
cout << n << "\n"; // 如果他可以把所有菜都打一遍,就直接输出n
}
}
return 0;
}
该做法的时间复杂度是,很明显超时了。
【做法二、前缀和+二分查找】
先对 数组排序,然后建立一个 数组,用于存放 ,然后用二分查找函数 _ 找出,最后输出即可,时间复杂度,代码实现如下
#include<bits/stdc++.h>
using namespace std;
int n,q;
int c[100100],x[100100],arr[100100];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for(int i = 1;i <= n;i++){
cin >> c[i];
}
cin >> q;
for(int i = 1;i <= q;i++){
cin >> x[i];
}
sort(c + 1,c + 1 + n);
for(int i = 1;i <= n;i++){
arr[i] = arr[i - 1] + c[i];
}
for(int i = 1;i <= q;i++){
int y = upper_bound(arr + 1,arr + 1 + n,x[i]) - arr;
if(y == n){
if(arr[y] > x[i]){
cout << y - 1 << "\n";
}
else{
cout << y << "\n";
}
}
else{
cout << y - 1 << "\n";
}
}
return 0;
}
完结撒花!!!
制作不易,点个赞吧!