codeforces_351b

好吧。。比赛的时候没有做出来。

主要是只考虑了所有整数都取向下的情景,没有考虑到所有整数都往上取。

首先区分出整数和小数,整数的差是没有影响的,主要在于小数的差。先把所有小数的和求出来。

因为取上为n个,取下为n个。对于所有小数来说哪一个小数取上和哪一个小数取下是没有区别的。假设0.3 0.5 0.7 0.8 ...假设里面有2个可以取上,2个可以取下。

无论是哪2个取上取下最后一定是0  + 0 + 1 + 1 = 2的结果。假设都是小数就好做了,因为2 * n个小数取上取下结果一定是n。

现在加入了整数,整数取上取下是没有区别的,所以小数取的和就不一定是n了,可以在n的周围进行变化,多一个整数就可以向下浮动1,或者向上浮动1。

如上面的0.3 0.5 0.7 0.8 0.6  3。多了0.6 和3。现在取4个上,4个下,要全是小数结果是4,但3是整数。3取上则小数多可以取一个下,结果就少1,3取下,小数就可以多一个

取上的,结果就多1.

那么有k个整数,(整数个数小于一半 < n) k个整数全取上的话,小数部分就可以只选取n - k个上,其余全下,那么和就是n - k

k个整数全取下的话,小数部分就可以只选取n - k个下,其余全上,那么和就是n,和可以在n - k到n之间波动。

同理整数个数多于一半 > n, n个全取上的话,小数部分全下,为 0,

n个全取下的话,小数部分全部为1,2 * n - k。

AC代码:

#include <cstring>
#include <cstdio>
#include <cmath>

const int MAX_NUMBER = 4006;
const double INF = 10000000.0;
const double eps = 1e-10;

double value[MAX_NUMBER];
int n, integer_number;
double sums_1;

int main() {

    scanf("%d", &n);
    integer_number = 0;
    sums_1 = 0;
    for (int i = 1; i <= 2 * n; i++) {
        scanf("%lf", &value[i]);
        if (fabs(value[i] - (int)value[i]) < eps) {
            integer_number++;
        }
        else {
            sums_1 += value[i] - (int)value[i];
        }
    }
    double ans = INF;
    if (integer_number > n) {
        for (int i = 0; i <= 2 * n - integer_number; i++) {
            double temp = fabs(i - sums_1);
            if (temp < ans) {
                ans = temp;
            }
        }
    }
    else {
        for (int i = n - integer_number; i <= n; i++) {
            double temp = fabs(i - sums_1);
            if (temp < ans) {
                ans = temp;
            }
        }
    }
    printf("%.3lf\n", ans);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值