Budget
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 95 Accepted Submission(s): 35
Problem Description
Avin’s company has many ongoing projects with different budgets. His company records the budgets using numbers rounded to 3 digits after the decimal place. However, the company is updating the system and all budgets will be rounded to 2 digits after the decimal place. For example, 1.004 will be rounded down
埃尔文的公司有许多正在进行的项目,包含着很多不同的预算。他的公司以3位实数的形式记录预算。但是,公司正在升级系统,所有预算值将在升级完成后保留两位小数点。比如说…………埃尔文想知道在升级前后的总预算差别。
to 1.00 while 1.995 will be rounded up to 2.00. Avin wants to know the difference of the total budget caused by the update
Input
The first line contains an integer n (1 ≤ n ≤ 1, 000). The second line contains n decimals, and the i-th decimal ai (0 ≤ ai ≤ 1e18) represents the budget of the i -th project. All decimals are rounded to 3 digits.
输入包含:预算个数n,n个保留三位小数的实数
Output
Print the difference rounded to 3 digits..
由于浮点数误差(由于二进制的缺陷,使得计算机无法准确表达一些数),使得无法对这个题进行乘1000再单独取出最后一位的直接求解。所以说必须另寻他路。
字符串可以解决这个问题。通过把这些小数输入到一个字符串中,我们可以免去一些没有意义的乘除(这就是导致误差的重要因素之一),直接通过下标访问最后一个数即可,然后模拟四舍五入算法就可解得答案。
思路整体如下:
- 通过字符串存储这些实数,并利用其特性计算答案
//#include<pch.h>
#include <iostream>
#include <cstdio>
#include <bits/stdc++.h>
#include <map>
#include <algorithm>
#include <stack>
#include <iomanip>
#include <cstring>
#include <cmath>
#define DETERMINATION main
#define lldin(a) scanf_s("%lld", &a)
#define println(a) printf("%lld\n", a)
#define reset(a, b) memset(a, b, sizeof(a))
const int INF = 0x3f3f3f3f;
using namespace std;
const double PI = acos(-1);
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int mod = 1000000007;
const int tool_const = 19991126;
const int tool_const2 = 33;
inline ll lldcin()
{
ll tmp = 0, si = 1;
char c;
c = getchar();
while (c > '9' || c < '0')
{
if (c == '-')
si = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
{
tmp = tmp * 10 + c - '0';
c = getchar();
}
return si * tmp;
}
///Untersee Boot IXD2(1942)
/**Although there will be many obstructs ahead,
the desire for victory still fills you with determination..**/
/**Last Remote**/
string strs[1500];
int DETERMINATION()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
ll n;
cin >> n;
ld ans = 0;
for (int i = 1; i <= n; i++)
cin >> strs[i];
for (int i = 1; i <= n; i++)
{
if (strs[i][strs[i].size()-1] - '0' >= 5)//四舍五入的模拟
ans += (10 - (strs[i][strs[i].size() - 1] - '0'));
else
ans -= (strs[i][strs[i].size() - 1] - '0');
}
cout << fixed << setprecision(3) << ans/1000<< endl;
return 0;
}
当然还有一个办法,自然就是java的BigDecimal类型,此类型可以进行严格浮点数运算使得不会造成精度丢失。
import java.math.*;
import java.text.DecimalFormat;
import java.util.*;
public class Main
{
public static void main(String[] args)
{
Scanner cin=new Scanner(System.in);
long n=cin.nextLong();
BigDecimal[] a=new BigDecimal[5000];
BigDecimal[] b=new BigDecimal[5000];
for(int i=1;i<=n;i++)
{
a[i]=cin.nextBigDecimal();
b[i]=a[i];
a[i]=a[i].setScale(2,BigDecimal.ROUND_HALF_UP);//四舍五入为两位小数
}
DecimalFormat df=new DecimalFormat("0.000");
BigDecimal ans=BigDecimal.valueOf(0);
for(int i=1;i<=n;i++)
{
ans=ans.add(a[i].subtract(b[i]));
}
System.out.println(df.format(ans));
cin.close();
}
}