题目:https://vjudge.z180.cn/contest/418003#problem/E
题意:总共10000个人,做了一项调查,统计出了数据,但是把这个数据的所有结果都四舍五入了,问你找出结果的最大值和最小值,也有结果不对的情况
解析:
其实这个题目很简单,当时也想出了解决的方法,但是在应用最大值得时候没有想过来,┭┮﹏┭┮。
干活:
%因为每一个结果都是四舍五入的,那么每一个值(x)得范围都是在
x - 50 到 x + 49 之间, 这是一定的,但是题目有约束条件,就是调查的总人数是10000个人,那么这些数的总和应该是10000,那么当每一个结果都是(四舍)出来的,那么原来的值应该都是x + 49,要求某一个值得最小,只需要将其他所有值最大,比如我们有 a, b, c, d 要求a的最小,只需将b, c, d最大即可,即a = 10000 - ( (b + 49) + (c + 49) + (d + 49) ), 当10000减得数越大,a的值就越小,但是a有自己结果的限制,就是咱们得到的这个结果在(五入)的过程中能得出来,即如过 result = 32, 但是咱们通过求最小值得到了31.22, 那么这个最小值是不对滴,应该是最小为31.50,那么结果应该对这两个值去max(见代码);反之亦然。。挺好理解的。(应该没人愿意看这文字。。。。)
% 判断impossible 的时候,先假设每一个值都是(四舍)得到的,那么原来的值应该是每一个值 + 49, 如果他们的和还是 < 10000那么无论怎样(五入),都得不到10000,反之一样。
% 当判断最大值和最小值的时候0 和 10000也是限制,挺好理解的。
代码:
#include <bits/stdc++.h>
#define lowbit(x) (x & (-x))
using namespace std;
const int mod = 1e9 + 7;
const int N = 1e4 + 50;
const int INF = 0x3f3f3f3f;
typedef long long ll;
string name[N];
int small[N], big[N];
int main()
{
//ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int p; cin >> p;
int sumbig = 0, sumsmall = 0;
for (int i = 1; i <= p; i++) {
cin >> name[i];
int t; cin >> t; t *= 100;
sumbig += t + 49;
sumsmall += t - 50;
big[i] = t + 49;
small[i] = t - 50;
}
if (sumsmall > 10000 || sumbig < 10000) {
cout << "IMPOSSIBLE" << endl;
return 0;
}
// 先求了一下总和,最下面的操作中会更容易的。
for (int i = 1; i <= p; i++) {
cout << name[i] << " ";
int t = 10000 - (sumbig - big[i]); // 其他最大,这个值本身最小。
printf("%.2lf ", max(0, max(small[i], t)) / 100.0);
t = 10000 - (sumsmall - small[i]); // 其他最小,这个值本身最大。
printf("%.2lf\n", min(10000, min(big[i], t)) / 100.0);
}
return 0;
}