小熊吃糖-2018笔试题

有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;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值