codeforces 351A A. Jeff and Rounding(★)

本文介绍了一种解决特定数学问题的算法,即给定2*n个数时,如何通过向上和向下取整来使得新旧数值之和的差距最小。通过分析数的小数部分并进行枚举操作,找到最优解。

题目大意:

给出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;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值