题目
题意:一个10000个人投票,然后根据投票比例四舍五入成现在的整数,问原来每个地方的最大比例和最小比例分别是多少
#include <iostream>
#include <string>
#include<bits/stdc++.h>
using namespace std;
char str[50001];
string names[50001];
int d[50001];
int main()
{
int n;
int sum = 0;
scanf("%d", &n);
for (int i = 0; i < n; ++i)
{
scanf("%s%d", str, &d[i]);
d[i] *= 100;
sum += d[i];
names[i] = str;
}
//要想有最大和最小,必须得有一个可以被补的,也必须有一个可以被舍的
//所以至少有一个大于等会0.5,至少有一个小于0.5
//假设原来有(n-1)个49是被舍掉变成现在的大小,那么就给他减去
//例如如果sum里面恰好有(n-1)是舍了49,那么现在的10000减去的就是原来没被四舍五入的正确人数,
//那么l就是剩余那一个被补上了一些人数弄成了现在的人数的差,如果sum有(n-2)个是从49舍掉的,那么l就是49+那个需要补上的人数的差,当然这里是负数
//l就代表可以最多拿出多少给其他地方补,当然最多拿出50,这样可以保证自己不掉落到下一个等级
int l = 10000 - sum - 49 * (n-1);
//假设原来有(n-1)个是被别的地方补了50到达现在的大小的,那么当减以sum的时候就多减了,这个时候再给他补上(n-1)个50
//这样r就代表最多可以被别的地方补多少,当然最多补49,如果补50,那么就会变成下一个等级
int r = 10000 - sum + 50 * (n-1);
if (r > 49) r = 49;
if (l < -50) l = -50;
if (l <= r) //如果l大于r,代表l那个式子需要n,r那个式子也需要n,就矛盾了所以就不成立
{
for (int i = 0; i < n; ++i)
{
printf("%s %.2f %.2f\n", names[i].c_str(),
max(0, d[i] + l) / 100.0,
min(10000, d[i] + r) / 100.0);
}
}
else printf("IMPOSSIBLE\n");
}