PAT_A1060
PAT甲级1060.
目录
A1060
题目
样例
样例1
输入:
3 12300 12358.9
输出:
YES 0.123*10^5
样例2
输入:
3 120 128
输出:
NO 0.120*10^3 0.128*10^3
补充样例1(关于0的情况)
输入:
3 0 0.000
输出:
YES 0.000*10^0
补充样例2(小于1的小数,有前导0)
输入:
5 0.1 00.100
输出:
YES 0.10000*10^0
补充样例3(大于1的小数,有前导0)
输入:
3 010.25 0010.23
输出:
YES 0.102*10^2
补充样例4(小于1的小数,小数点之后有0)
输入:
4 0.0015 0.00150034
输出:
YES 0.1500*10^-2
思路和坑点
对于科学计数法的求解,首先是解决0的问题,然后是有效位及其指数的确定,这里通过以下规则确定有效位,然后同时确定指数,最后比较并输出。
首先是要考虑数据过滤。包括特判0和前导0两个方面。
一、首先是特判0,凡是只有0或者.的都统一认为是0,如补充样例1所示。
二、如果不是0,则需要删除前导0,只留下有效位,此时分两种情况,一种是小于1的数000.0015和大于1的数12345.67,保留之后分别为.0015和12345.67
其次是要考虑指数的计算和有效位数补全的问题。
有效位数补全:对字符串的处理只留下第一个有效位之后的部分,然后如果少于有效位,补0。
指数的计算:有一下情况,正指数、如12345,指数为字符长度;12345.67指数为小数点‘.‘在字符串中的下标。负指数、如0.001234,指数为小数点到有效位之间0的个数,比如.到1之间有两个零,指数为-2
AC代码
#include<bits/stdc++.h>
using namespace std;
int n;
string trans(string str,int &e){
string ret=""; //ret为返回值,表示有效字段,e表示指数
int tag=0; //是否为0的标记
for(int i=0;i<str.size();i++){ //判断是不是0(凡是没有非零数字的都是0,比如0 0.00)
if(str[i]!='0'&&str[i]!='.'){
tag=1;break; //如果不是0,修改标记tag为1
}
}
if(tag==0){ //如果是0,有效字段为n个0,并且指数为0
for(int i=0;i<n;i++)
ret+='0';
e=0;
}
else{
while(1){ //去除前导0
if(str[0]!='0')
break;
else str.erase(str.begin());
}
int pos=str.find('.'); //查找点的下标
if(pos==string::npos) //如果没有点 ,则是整数,e为字符串长度
e=str.size();
else if(pos==0){ //如果第一个是点,则这个数小于1,e<=0;
e=0; str.erase(str.begin());
while(str[0]=='0'){ //如果小数点和第一个非零数字之间还有0,则e--,并清除这些0
str.erase(str.begin());
e--;
}
}
else{
e=pos; //如果该数大于1,则指数等于点的下标 比如1234.56
str.erase(pos,1); //删除点
}
for(int i=0;i<n;i++){ //获取n位有效数字
if(i<str.size())
ret+=str[i];
else //如果字符串不够n位,补齐为0
ret+='0';
}
}
return ret;
}
int main(void){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt","r",stdin);
#endif
string a,b;
int ea,eb;
ea=eb=0;
cin>>n>>a>>b;
a=trans(a,ea); b=trans(b,eb);
if(a==b)
printf("YES 0.%s*10^%d",a.c_str(),ea);
else
printf("NO 0.%s*10^%d 0.%s*10^%d",a.c_str(),ea,b.c_str(),eb);
return 0;
}