有n只小熊,他们有着各不相同的战斗力。每次他们吃糖时,会按照战斗力来排,战斗力高的小熊拥有优先选择权。前面的小熊吃饱了,后面的小熊才能吃。每只小熊有一个饥饿值,每次进食的时候,小熊们会选择最大的能填饱自己当前饥饿值的那颗糖来吃,可能吃完没饱会重复上述过程,但不会选择吃撑。
现在给出n只小熊的战斗力和饥饿值,并且给出m颗糖能填饱的饥饿值。
求所有小熊进食完之后,每只小熊剩余的饥饿值。
输入描述:
第一行两个正整数n和m,分别表示小熊数量和糖的数量。(n <= 10, m <= 100) 第二行m个正整数,每个表示着颗糖能填充的饥饿值。 接下来的n行,每行2个正整数,分别代表每只小熊的战斗力和当前饥饿值。 题目中所有输入的数值小于等于100。
输出描述:
输出n行,每行一个整数,代表每只小熊剩余的饥饿值。
示例1
输入
2 5 5 6 10 20 30 4 34 3 35
输出
4 0
说明
第一只小熊吃了第5颗糖 第二只小熊吃了第4颗糖 第二只小熊吃了第3颗糖 第二只小熊吃了第1颗糖
思路:
这题不难,按照题意可以得到一个线性的解法,主要是注意细节。另外也可以尝试用二分的方法,可以进一步减少时间复杂度。
这次先采用线性的解法。至于代码中为什么可以想到定义一个bear的结构体,主要是考虑到题目中熊有fight,hunger和id三个属性,并隐含着要按照fight从大到小排序,故想到定义一个结构体,并自定义从大到小排序cmp函数。
代码:
#include <iostream>
#include<algorithm>
using namespace std;
struct bear
{
int fight; //熊的战斗力
int hunger; //熊的饥饿值
int id; //输入时的id
};
int n, m; //n<=10,m<=100
int a[105]; //糖的数量
int flag[105] = {0};//0表示糖果没被吃掉
bear b[15]; //熊的数量
//int valPerbear;
int res[15] = {0};//熊进食后的饥饿值
bool cmp(bear a,bear b){ //根据熊的战力来从大到小进行排序
return a.fight > b.fight;
}
int hungerVal(int i){
for (int j = m-1; j >=0;j--)//吃糖的顺序:能填充的饥饿值从大到小
{
if ( flag[j] ==0 && b[i].hunger >= a[j]){ //由于糖吃过了就没了,所以定义一个flag来
//判断第j个糖是否已经被吃了,当然也可以采
//取把吃过的糖的填充饥饿值的能力置为0;
b[i].hunger -= a[j];
flag[j] = 1;
//a[j] = 0; //把吃过的糖能填充的饥饿值置为0
}
}
return b[i].hunger;
}
int main(){
cin >> n >> m;
for (int i = 0; i < m;i++)
{
cin >>a[i] ;
}
sort(a, a + m);//默认是从小到大
for (int j = 0; j < n; j++){
cin >> b[j].fight >> b[j].hunger;
b[j].id = j;
}
sort(b, b + n, cmp); //从大到小
for (int i = 0; i < n;i++)
{
res[b[i].id]= hungerVal(i);
}
for (int i = 0; i < n;i++)
{
cout << res[i] << endl;
}
return 0;
}