题目大意:
给出2*n个数,n个向上取整,n个向下取整,求新的数的和与原始的数的和的最小差距。
题目分析:
- 机智的人会发现,先对所有的数的小数部分取和,然后如果出现一个向上取整的,那么sum的变化一定是1,所以只和向上取整的数的个数有关系,而向上取整和向下取整的个数已经确定,只有存在小数部分是0的情况的时候,值会不同,因为它转换为向上取整和向下取整的值是不变的。
- 所以做法是,求得所有数小数部分的和,然后我们枚举在向上取整的n个数中,0占i个,然后当前这种情况的答案就是sum-(n-i)。
- 我们枚举所有情况取最小即可。
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <cstdlib> #include <algorithm> #include <cmath> #include <vector> #include <set> #include <list> #include <queue> #include <map> #include <stack> using namespace std; #define L(i) i<<1 #define R(i) i<<1|1 #define INF 0x3f3f3f3f #define pi acos(-1.0) #define eps 1e-6 #define maxn 200010 #define MOD 1000000007 int n,k,d; double a[maxn]; int flag[maxn]; int main() { int t,C = 1; while(scanf("%d%d",&n,&k) != EOF) { int k = 0,num = 0; memset(flag,0,sizeof(flag)); double sum = 0; for(int i = 0; i < 2*n; i++) { double d; scanf("%lf",&d); if(d - floor(d) < eps) num++; else { a[k++] = d - floor(d); sum += a[k-1]; } } double ans = INF; for(int i = n-num; i <= n; i++) ans = min(ans,fabs(sum-i)); printf("%.3f\n",ans); } return 0; }