题意
给出一些小数,它们的和为0,现在让你将小数变成整数,可以向上取整,也可向下取整,但是要保证最终生成的整数的和也要为0
思路
首先明确一点,向上取整与向下取整的结果之差为1,所以我们不妨对每一个数都向下取整,然后统计他们的和.如果和也为0,那么就是按向下取整来输出,否则的话这个和一定是负数,因为向下取整只会让原来所有数的和变小.然后取绝对值,假设值为p,那么在输出的时候只要选p个数向上取整,其他的向下取整就行.有一个细节要提一下,就是原来如果输入的数就已经是整数,那么这个数是不能向上取整的,只能对小数向上取整,下面看代码:
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const double eps=1e-8;
double a[N];
int flag[N];
int sign(double x){
if (fabs(x)<eps) return 0;
else return x<0?-1:1;
}
int main(){
int n;
scanf("%d",&n);
ll sum=0;
for (int i=1;i<=n;i++){
scanf("%lf",&a[i]);
if (sign(a[i]-floor(a[i]))==0) flag[i]=1; //flag数组表示这个位置的数是整数,等下不能拿来操作
sum+=floor(a[i]);
}
//for (int i=1;i<=n;i++) printf("%.0f\n",floor(a[i]));
//printf("%lld",sum);
if (sum==0){
for (int i=1;i<=n;i++){
printf("%.0f\n",floor(a[i]));
}
}
else if (sum<0){
ll p=0-sum;
for (int i=1;i<=n;i++){
if (flag[i]) printf("%.0f\n",floor(a[i]));
else if (p>0){
printf("%.0f\n",floor(a[i])+1);
p--;
}
else printf("%.0f\n",floor(a[i]));
}
}
return 0;
}