解题思路:刚开始读不懂题意,不知道到底让求什么,看着测试数据也很奇怪。根据题意,目的要求是“多退少补”,那么可以把学生分成两组,一组是垫付的费用大于平均费用的,一组是小于等于平均费用的,垫付多的学生应该退还钱款,垫付少的应该收取费用。而所求的是需要最少的那部分。即让求每个学生平摊支出所需的最小总“交易”金额。首先计算“平均费用”,由于要求支出差距在1分钱以内,故可以考虑在计算时取小数点后两位,对于第三位以后的数采用四舍五入的方法。可以截取浮点数中的部分小数位:sprintf( tmp, "%.2lf", ave); sscanf( tmp, "%lf", &ave); 其中 ave 中为要操作的浮点数,而 tmp 为一字符数组。
View Code
1 #include<iostream>
2 #include<cstdio>
3 using namespace std;
4 #define MAX 1005
5 double a[MAX];
6 char tmp[MAX]; // 用于截取小数点后前两位时用
7
8 int main()
9 {
10 int i,n;
11 while(cin>>n&&n)
12 {
13 double ave,sum= 0.0;
14 for(i= 0;i<n;i++)
15 {
16 cin>>a[i];
17 sum+=a[i];
18 }
19 ave=sum/n;
20 // 截取浮点数 ave 中两位小数位
21 sprintf(tmp, " %.2lf ",ave);
22 sscanf(tmp, " %lf ",&ave);
23 double t= 0.0,k= 0.0;
24 for(i= 0;i<n;i++)
25 if(a[i]>ave) t+=(a[i]-ave); // 多退
26 else k+=(ave-a[i]); // 少补
27 if(k>t) printf( " $%.2lf\n ",t);
28 else printf( " $%.2lf\n ",k);
29 }
30 return 0;
31 }
2 #include<cstdio>
3 using namespace std;
4 #define MAX 1005
5 double a[MAX];
6 char tmp[MAX]; // 用于截取小数点后前两位时用
7
8 int main()
9 {
10 int i,n;
11 while(cin>>n&&n)
12 {
13 double ave,sum= 0.0;
14 for(i= 0;i<n;i++)
15 {
16 cin>>a[i];
17 sum+=a[i];
18 }
19 ave=sum/n;
20 // 截取浮点数 ave 中两位小数位
21 sprintf(tmp, " %.2lf ",ave);
22 sscanf(tmp, " %lf ",&ave);
23 double t= 0.0,k= 0.0;
24 for(i= 0;i<n;i++)
25 if(a[i]>ave) t+=(a[i]-ave); // 多退
26 else k+=(ave-a[i]); // 少补
27 if(k>t) printf( " $%.2lf\n ",t);
28 else printf( " $%.2lf\n ",k);
29 }
30 return 0;
31 }