题型:数学
题意:
有2n个浮点数a1, a2, ..., a2n,现在对其中n个数进行向上或向下取整操作得到b1,b2,...,b2n,使得
|(a1+a2+...+a2n)-(b1+b2+...+b2n)|最小,输出这个最小值。
分析:
先将所有的数进行向下取整,然后将其小数部分相加得到sum,因为向下取整与向上取整相差1,所以每将一个向下取整的数变成向上取整,sum就会减掉1(前提是这个变化的数不是整数)。
所以就将sum往下减就可以了,如果要变化一些数,其中有cnt个非整数,那么sum就变成了fabs(sum-k)。
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define eps 1e-10
using namespace std;
double a[5000],b1[5000],b2[5000];
int main(){
int n;
while(~scanf("%d",&n)){
double sum=0.0;
int cnt1=0,cnt2=0;
for(int i=1;i<=n*2;i++){
scanf("%lf",&a[i]);
b1[i] = a[i] - (double)floor(a[i]);
sum += b1[i];
if(floor(a[i]) != ceil(a[i])) cnt1++;
else cnt2++;
}
//cout<<"sum = "<<sum<<endl;
//cout<<"cnt = "<<cnt<<endl;
double ans=9999999.0;
int k = min(cnt1,n);
for(int i=0;i<=k;i++){
if(i+cnt2>=n){
ans = min(fabs(sum-i*1.0),ans);
}
}
printf("%.3lf\n",ans);
}
return 0;
}
/*
3
0.000 0.500 0.750 1.000 2.000 3.000
3
4469.000 6526.000 4864.000 9356.383 7490.000 995.896
7
2341.538 9232.119 6646.930 9316.834 5684.000 9078.705 7773.000 3823.674 6357.022 9866.925 310.271 6554.778 8341.098 8407.987
9
5528.000 205.031 5245.169 8832.592 385.656 7126.360 3988.000 9542.000 3044.042 5288.351 9342.000 9979.021 7096.000 5159.200 9400.000 4996.735 1698.000 5403.939
1
6418.669 157.986
7
223.000 322.652 677.700 3852.000 2568.390 2410.713 3202.511 2122.870 1566.689 8841.790 8176.424 74.586 3834.000 6847.000
2
0.100 0.100 0.100 0.100
ans = 1.600
5
0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001 0.001
ans = 4.990
3
0.900 0.900 0.900 0.900 0.900 0.000
ans = 1.500
*/