贪心算法(2)

题目描述:

通过悬崖的yifenfei,又面临着幽谷的考验——
幽谷周围瘴气弥漫,静的可怕,隐约可见地上堆满了骷髅。由于此处长年不见天日,导致空气中布满了毒素,一旦吸入体内,便会全身溃烂而死。
幸好yifenfei早有防备,提前备好了解药材料(各种浓度的万能药水)。现在只需按照配置成不同比例的浓度。
现已知yifenfei随身携带有n种浓度的万能药水,体积V都相同,浓度则分别为Pi%。并且知道,针对当时幽谷的瘴气情况,只需选择部分或者全部的万能药水,然后配置出浓度不大于 W%的药水即可解毒。
现在的问题是:如何配置此药,能得到最大体积的当前可用的解药呢?
特别说明:由于幽谷内设备的限制,只允许把一种已有的药全部混入另一种之中(即:不能出现对一种药只取它的一部分这样的操作)。

输入:

输入数据的第一行是一个整数C,表示测试数据的组数;
每组测试数据包含2行,首先一行给出三个正整数n,V,W(1<=n,V,W<=100);
接着一行是n个整数,表示n种药水的浓度Pi%(1<=Pi<=100)。

输出:

对于每组测试数据,请输出一个整数和一个浮点数;
其中整数表示解药的最大体积,浮点数表示解药的浓度(四舍五入保留2位小数);
如果不能配出满足要求的的解药,则请输出0 0.00。

样例输入:
3
1 100 10
100
2 100 24
20 30
3 100 24
20 20 30
样例输出:
0 0.00
100 0.20
300 0.23
本题的解决方法:
    按照溶液浓度降序排列,每次都选取浓度最小的溶液(因为所有溶液的体积是一样的),如果---选取的溶液浓度和 < W*count(count选取的溶液的个数),则不再继续选取溶液,输出结果。
 
 
#include <stdio.h>
#include <algorithm>
using namespace std;



int arr[101];
int main()
{
	int C,n,V,M;
	while(scanf("%d",&C)!=EOF){
		while(C--){
			scanf("%d%d%d",&n,&V,&M);
			for(int i = 0;i <n;i++){
				scanf("%d",&arr[i]);
			}
			sort(arr,arr+n);
			int v,m;
			v = 0;m = 0;
			int count = 0;
			for(int i = 0; i< n;i++){
				int temp = m+arr[i];
				if(temp <= M*(i+1)){
					m = temp;
					v += V;
					count++;
				}else{
					break;
				}
			}
			if(v==0){
				printf("0 0.00\n");
			}else{
				//用int型绕开了用double时可能会出现的种种问题,但最后算浓度时,式子写错了,写成了m/v所以一直报WA
				printf("%d %.2lf\n",v,(double)m/count/100);
			}
		}
	}
	return 0;
}

 

 

 

题目描述:

Long time ago , Kitty lived in a small village. The air was fresh and the scenery was very beautiful. The only thing that troubled her is the typhoon.

When the typhoon came, everything is terrible. It kept blowing and raining for a long time. And what made the situation worse was that all of Kitty's walls were made of wood.

One day, Kitty found that there was a crack in the wall. The shape of the crack is
a rectangle with the size of 1×L (in inch). Luckly Kitty got N blocks and a saw(锯子) from her neighbors.
The shape of the blocks were rectangle too, and the width of all blocks were 1 inch. So, with the help of saw, Kitty could cut down some of the blocks(of course she could use it directly without cutting) and put them in the crack, and the wall may be repaired perfectly, without any gap.

Now, Kitty knew the size of each blocks, and wanted to use as fewer as possible of the blocks to repair the wall, could you help her ?

输入:

The problem contains many test cases, please process to the end of file( EOF ).
Each test case contains two lines.
In the first line, there are two integers L(0<L<1000000000) and N(0<=N<600) which
mentioned above.
In the second line, there are N positive integers. The ith integer Ai(0<Ai<1000000000 ) means that the ith block has the size of 1×Ai (in inch).

输出:

For each test case , print an integer which represents the minimal number of blocks are needed.
If Kitty could not repair the wall, just print "impossible" instead.

样例输入:
5 3
3 2 1
5 2
2 1
样例输出:
2
impossible
//本题目不难,只是简单地贪心算法应用,需要注意的地方,在代码中出错点处有注释
 
 
#include <stdio.h>
#include <algorithm>
using namespace std;

bool cmp(unsigned int x,unsigned int y)
{
	return x > y;
}


unsigned int arr[601];
int main()
{
	unsigned int L;
	int n;
	while(scanf("%u%d",&L,&n)!=EOF){
		for(int i = 0; i <n;i++){
			scanf("%u",&arr[i]);
		}
		sort(arr,arr+n,cmp);
		unsigned int result = 0;
		int count =0;
		int leap = 0;
		for(int i = 0;i <n;i++){
			if(result < L){
				result += arr[i];
				count++;
			}
		}
		/***************************************************
		最开始的时候代码块是(出错点)
		for(int i = 0;i <n;i++){
		    if(result < L){
			   result += arr[i];
			   count++;
			}else{
			   leap = 1;
			   break;
			}
		}
		if(leap == 0){
		   printf("impossible\n");
		}else{
		   printf("%d\n",count);
		}
		是根据leap判断来做输出,但要考虑到一种极端情况,只有一块可用木板,
		且该块木板的大小大于窟窿的大小,这时跳不到else中,自然输出也不对了
		****************************************************/
		if(result < L){
			printf("impossible\n");
		}else{
			printf("%d\n",count);
		}
	}
	return 0;
}


 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值