题目的大意是给你2*n个浮点数,要求你选出n对浮点数,每一对浮点数其中一个数取上限,另一个数取下限,然后求2*n个处理后浮点数的和与处理前浮点数的和的差的绝对值。
即min |(a1+a2+.....+an)-([ai1+aj1]+[ai2+aj2]+.....+[ain+ajn])|;
解题思路:
要注意的是 例如 2.0的上限和下限都是2.0;
首先对每一个浮点数都取其下限,这样得到的差值就是所有浮点数小数部分的和;然后则需要从2*n个数里面选出n个数取其上限,即下限加1,而如果这个数是个整数,那么不需要加1;因此统计加1个数的上限和下限即可;然后选择min abs(小数部分的和-加1的个数);
代码:
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; // int n; double a,sum; int z,nz; //z为小数部分为0的数的个数,nz为非零的个数 double ans=10000000; int main() { cin>>n; sum=0.0; z=nz=0; for(int i=1;i<=2*n;i++) { scanf("%lf",&a); a=a-(int)a; sum+=a; if(a==0) z++; else nz++; } int sup,inf; if(nz<=z) { inf=0; sup=nz; } else { inf=n-z; sup=n; } for(int i=inf;i<=sup;i++) ans=min(ans,abs(i-sum)); printf("%.3lf ",ans); }