原题目: http://codeforces.com/contest/68/problem/B
题意: 给出N个能量值a1, a2...an, 能量之间能互相转换, 但转换时会有k百分比的损失, 要求出最后各能量值相等时的最大值.
解题思路: 设最后达到平衡时能量值为 x, 则在转换时总共损失了能量 (1式)(a1 + a2 +...+ an ) - N * x . 对于每一个a值,如果 a > x, 那么它必须要转换 a - x 单位能量, 之间损失 (a - x) * (k / 100), 问题是我们如何知道 ai 是否大于 x 呢? 这是问题所在也是解题的关键.我们可以从反面来进行贪心, 将N个ai值按从大到小的顺序排序, 假设前面 c 个a值都大如 x ,那么损失值为(2式) (a1 + a2 +...+ ac) - c * x, (1式)与(2式)建立相等关系, 可以求出一个 x 值, 用 x 与 a[c + 1], 作对比,如果 x 还小于 a[c + 1], 那么还可以继续进行贪心,直到大于.
1
#include
<
iostream
>
2 #include < cstdio >
3 #include < string >
4 #include < cstring >
5 #include < algorithm >
6 #include < vector >
7 #include < map >
8
9 using namespace std;
10
11 const int MAX = 10000 + 1 ;
12 bool comp( const double & a, const double & b)
13 {
14 return a > b;
15 }
16 int main()
17 {
18 // freopen("in.txt","r",stdin);
19 int n;
20 double k;
21 double energy[MAX];
22 double energySum = 0 ;
23 scanf( " %d%lf " , & n, & k);
24 for ( int i = 0 ; i < n; ++ i)
25 {
26 scanf( " %lf " , & energy[i]);
27 energySum += energy[i];
28 }
29 sort(energy, energy + n, comp);
30 k /= 100 ;
31 double sum = 0 ;
32 double ans = 0 ;
33 energy[n] = 0 ;
34 for ( int i = 0 ; i < n; ++ i)
35 {
36 sum += energy[i];
37 ans = (k * sum - energySum) / ((i + 1 ) * k - n);
38 if (ans >= energy[i + 1 ])
39 {
40 break ;
41 }
42 }
43 printf( " %.9lf\n " , ans);
44 return 0 ;
45 }
2 #include < cstdio >
3 #include < string >
4 #include < cstring >
5 #include < algorithm >
6 #include < vector >
7 #include < map >
8
9 using namespace std;
10
11 const int MAX = 10000 + 1 ;
12 bool comp( const double & a, const double & b)
13 {
14 return a > b;
15 }
16 int main()
17 {
18 // freopen("in.txt","r",stdin);
19 int n;
20 double k;
21 double energy[MAX];
22 double energySum = 0 ;
23 scanf( " %d%lf " , & n, & k);
24 for ( int i = 0 ; i < n; ++ i)
25 {
26 scanf( " %lf " , & energy[i]);
27 energySum += energy[i];
28 }
29 sort(energy, energy + n, comp);
30 k /= 100 ;
31 double sum = 0 ;
32 double ans = 0 ;
33 energy[n] = 0 ;
34 for ( int i = 0 ; i < n; ++ i)
35 {
36 sum += energy[i];
37 ans = (k * sum - energySum) / ((i + 1 ) * k - n);
38 if (ans >= energy[i + 1 ])
39 {
40 break ;
41 }
42 }
43 printf( " %.9lf\n " , ans);
44 return 0 ;
45 }