思路:
这道题和D那道修墙的题目差不多,对药水浓度进行从小到大的排序,依次取浓度最小的药水加入,知道达到或超过目标浓度。
解答:
/*
《算法笔记》codeup 100000584 问题 F: 迷瘴
*/
#include <cstdio>
#include <algorithm>
using namespace std;
int main() {
int test_num;
while(scanf("%d", &test_num) != EOF) {
while(test_num--) {
int drug_num; // 药水数量
int volume; // 药水体积
double temp_target_potency; // 目标浓度*100
double target_potency; // 目标浓度(百分比)
scanf("%d %d %lf", &drug_num, &volume, &temp_target_potency); // 要想得到double类型的结果需要至少一个double类型的运算数
target_potency = temp_target_potency / 100; // 生成百分比表示的目标浓度
double potency[drug_num]; // 药水浓度数组
for(int i = 0; i <= drug_num - 1; i++) {
double temp;
scanf("%lf", &temp);
potency[i] = temp / 100; // 生成百分比表示的药水浓度
}
sort(potency, potency + drug_num); // 对药水按照浓度从小到大排序
int temp_volume = 0; // 已调制的药水的体积
int feasible_volume = 0; // 可行的已调制药水的体积
double temp_potency = 0; // 已调制的药水的浓度
double feasible_potency = 0; // 可行的已调制药水的浓度
for(int i = 0; i <= drug_num - 1; i++) {
temp_potency = ((temp_potency * temp_volume) + (potency[i] * volume)) / (temp_volume + volume); // 计算加入下一瓶药水后的总浓度
if (temp_potency<= target_potency) { // 如果加入下一瓶药水后总浓度没超过目标浓度,则
temp_volume += volume; // 已调制药水的体积增加一瓶药水的体积
feasible_volume = temp_volume; // 更新可行体积
feasible_potency = temp_potency; // 更新可行浓度
}
else // 如果加入下一瓶药水后总浓度超过目标浓度,则
break; // 跳出循环,不再加入药水
}
printf("%d %.2lf\n", feasible_volume, feasible_potency); // %.x包含四舍五入的作用
}
}
return 0;
}
坑:
- 查了半天四舍五入的写法,后面才知道直接用%.2lf就可以实现输出四舍五入保留两位小数的结果。
- 结果一直差很远,查bug好久才发现是计算浓度的代码里被除数部分没有加括号。
笔记:
-
%.x包含四舍五入的作用。
-
查bug可以:①先全部注释掉,分别检查,通过再取消注释。②带入特殊值数据。
-
要想得到double类型的结果需要至少一个double类型的运算数