题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4493
题目意思:
给小数点后两位的12个月的工资,求出平均工资,输出离小数点后第二位最近的两位小数,尾部零不输出。
解题思路:
这题一开始先除以12的话,有精度损失(比如都是12.4449999999999,结果算出来是12.45,应该是12.44),所以先模拟除以12,得到小数点后的第三位数,大于等于5第二位就进位,否则舍掉。
用a[0]表示12个月收入和的整数部分,a[1]表示第一位小数,a[2]表示第二位小数。然后模拟高精度除法,求出除以12后的第三位小数。
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#define eps 1e-6
#define INF 0x1f1f1f1f
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; //freopen("data.in","r",stdin);
//freopen("data.out","w",stdout); int ans[4],a[3];
int main()
{
int t; scanf("%d",&t);
while(t--)
{
double sum=0,tt;
for(int i=1;i<=12;i++)
scanf("%lf",&tt),sum=sum+tt;
// printf("%lf\n",sum);
a[0]=(int)sum; //整数部分
a[1]=(int)(sum*10)%10; //第一位小数部分
a[2]=(int)(sum*100)%10; //第二位小数部分
//printf("%d %d %d\n",a[0],a[1],a[2]); int la=0;
for(int i=0;i<=2;i++) //求出小数后面第三位
{
ans[i]=(a[i]+la*10)/12;
la=(a[i]+la*10)%12;
}
ans[3]=la*10/12;
if(ans[3]>=5)//进位
{
ans[2]++;
if(ans[2]>=10) //进位
{
ans[2]=0;
ans[1]++;
if(ans[1]>=10)
{
ans[1]=0;
ans[0]++;
}
}
}
printf("$%d",ans[0]);
if(ans[1]) //去掉尾部0
{
printf(".%d",ans[1]);
if(ans[2])
printf("%d",ans[2]);
}
else if(ans[2]) //注意.0几
printf(".%d%d",ans[1],ans[2]);
putchar('\n'); }
return 0;
}
/*
1.4449999
1.4449999
1.4449999
1.4449999
1.4449999
1.4449999
1.4449999
1.4449999
1.4449999
1.4449999
1.4449999
1.4449999
*/