题目来源:PAT (Advanced Level) Practice
If a machine can save only 3 significant digits, the float numbers 12300 and 12358.9 are considered equal since they are both saved as 0.123×105 with simple chopping. Now given the number of significant digits on a machine and two float numbers, you are supposed to tell if they are treated equal in that machine.
Input Specification:
Each input file contains one test case which gives three numbers N, A and B, where N (<100) is the number of significant digits, and A and B are the two float numbers to be compared. Each float number is non-negative, no greater than 10100, and that its total digit number is less than 100.
Output Specification:
For each test case, print in a line YES
if the two numbers are treated equal, and then the number in the standard form 0.d[1]...d[N]*10^k
(d[1]
>0 unless the number is 0); or NO
if they are not treated equal, and then the two numbers in their standard form. All the terms must be separated by a space, with no extra space at the end of a line.
Note: Simple chopping is assumed without rounding.
Sample Input 1:
3 12300 12358.9
Sample Output 1:
YES 0.123*10^5
Sample Input 2:
3 120 128
Sample Output 2:
NO 0.120*10^3 0.128*10^3
words:
significant 重要的,有效的 chopping 降低,砍,劈 rounding 舍入
题意:
给定一个整数n和两个小数a和b,判断a和b在n个有效数字的情况下是否相等,并且以“0.d[1]...d[N]*10^k
“的标准形式输出;
思路:
1. 由于a和b可能很大,达到100位,所以使用字符串形式保存和处理a和b;
2. 创建一个函数abc(),用于将输入的小数转化为具有n位有效数字的标准形式的数;
a. 函数abc()中,首先寻找待转换小数a中的小数点位置p,若没有小数点则p为a的长度,若有要记录小数点位置且删除小数点;
b. 设置ten来记录变换前后小数点的位移值,后边用它表示10的指数,左移为正,右移为负;
c. 设置flag用于标记第一个非0数字的出现;
d. 遍历小数字符串a,当出现第一个非0数字时(!flag&&a[i]!='0'),计算ten=p-i,并且置flag=true;从该字符开始记录n个字符作为有效数字到字符串ans中或者直到遍历完所有字符;
e. 若ans的长度小于n则在后边用‘0’补充;
f. 若a中的数字全为0(flag==false),则返回 "0."+ans+"*10^0",否则返回 "0."+ans+"*10^"+to_string(ten);
3. 判断a和b的标准形式是否相同,相同则a和b在机器中被认为相等并输出“YES”和其中一个的标准形式,否则则不相等并输出“NO”和他们各自的标准形式;
//PAT ad 1060 Are They Equal
#include <iostream>
using namespace std;
string abc(int n,string a) //将a转化为题目要求的标准形式 ,n为小数点后数的长度
{
int p=a.find('.'); //寻找小数点的位置
int l=a.size();
string ans; //结果
if(p==a.npos) //没有小数点
p=l;
else
{
a.erase(p,1); //删除小数点
l--;
}
bool flag=false; //标记是否有非0出现
int ten;
for(int i=0;i<l&&ans.size()<n;i++)
{
if(!flag&&a[i]!='0') //第一个非0
{
flag=true;
ten=p-i;
}
if(flag) //从第一个非零开始记录有效数字 ,直到没有数字或者达到要求的长度n
ans.push_back(a[i]); //在ans的后边追加字符a[i]
}
ans.resize(n,'0'); //若有效数字的长度小于0则后面加0补充
if(!flag)
ans="0."+ans+"*10^0"; //若所有的数字都为0,即a的值为0
else
ans="0."+ans+"*10^"+to_string(ten);
return ans;
}
int main()
{
int n;
string a,b;
cin>>n>>a>>b;
string sa=abc(n,a); //将a转化为题目要求的标准形式
string sb=abc(n,b); //将b转化为题目要求的标准形式
if(sa==sb)
cout<<"YES"<<" "<<sa<<endl;
else
cout<<"NO"<<" "<<sa<<" "<<sb<<endl;
return 0;
}