题目分析:
- 由于每瓶药水体积相同,要求体积最大等同于瓶数最多。
- 要求浓度不大于W%,所以我们需要从浓度较低的药水开始添加,直到浓度刚好不大于W%。
- 一瓶浓度为20%的药水和一瓶浓度为30%的体积相同的药水混合,浓度为25% = (20%+30%)/2。
- 体积相同则混合后浓度与体积无关,3瓶以上同理。
解题思路:
- 将药水浓度a[]排序,优先添加低浓度药水。
- 当添加了第1~i瓶药水时,药水浓度为P/i,(P = a[1]~a[i]之和)。
- 如果当前药水浓度恰好超过了要求浓度W,则退回一步,i--。此时浓度正好不大于W。
- 输出体积i*v和浓度P/i。
代码如下:
#include <bitsstdc++.h>
using namespace std;
typedef long long ll;
int a[105];
int main(){
ios::sync_with_stdio(false);
int t;
cin >> t;
int n,v,m;
while(t--){
cin >> n >> v >> m;
for(int i = 1;i <= n; ++i){
cin >> a[i];
}
//按浓度排序所有药水,从浓度较低的开始添加
sort(a+1,a+1+n);
int i;
a[0] = 0;
//添加第1~i瓶药水,当前药水浓度为a[1]加到a[n]除以i
for(i = 1;i <= n; ++i){
//将浓度加起来
a[i] += a[i-1];
//如果浓度大于要求浓度,则撤回当前这瓶药水
// 实际表达式为a[i]/i > m
//a[i]不为浮点型除法会丢失精度,故用以下表达式
if(a[i] > m*i) break;
}
i--; //撤回一步,保证浓度小于等于要求浓度m
if(i == 0){
printf("0 0.00
");
}else{
printf("%d %.2lf
" , i*v,1.0*a[i]/i/100);
}
}
return 0;
}