PAT_甲级_1060 Are They Equal

题目大意:

给定两个位数不超过100的非负浮点数,如果保留n位有效数字的情况下写成0.@@@@*10^@的形式,如果两者相同,则输出YES和该数字,如果不同输出NO并且分别输出2个数。

算法思路:

仔细思考下,这种形式和科学技术法很相似但是有不同于科学计数法,因为前面一定得是0.开头,那么输入的数字的形式按照道理来说只有一种,那就是$abcd.efg$,但是在这里仔细分成2类,一类就是$0.efg$ 的形式,一类就是$abcd.@@@$ 的形式(好像和没说一样,哈哈哈),这里把第一类分出来是因为在处理第二类的时候会出现$abcd$全部是0的情况(这是一个陷阱),这样就退化到了第一类,然后就是输入的数字有可能本来就是第一类,这样方便代码解耦(个人观点),接下来就具体说这2类数字的处理方法.

第一类$0.efg$

首选我们知道最后一定是0.开头,所以使用string r="0."保存最后结果,这类数字分为2种情况,一种就是小数点后面全是0,这种情况下就直接让r后面添加n个0和10^0即可(这也是一个陷阱),另外一种就是小数点后面有不为0的数字,那么用index保存其位置,让r添加原字符串的index到最后位置的子串,注意如果该子串的长度s.size()-index,则得在后面补充0,使得其小数点后面的有效位为n(这也是一个陷阱),然后再添加指数部分,指数的次幂pos+1-index(index-pos-1就是小数点到不为0之间0的个数,相反数就是指数部分) 。最后返回r即可。该类数字使用type1函数处理。

第二类$abcd.@@@$(包含整数)

这类数字也分为2种情况,第一种情况就是小数点前面全部是0,这样的数字(比如0000.@@@,等效于0.@@@)等价于第一类数字,直接将小数点前面的一个0到最后位置截断,然后调用type1处理即可,第二种情况就是小数点前面有不为0的数字,这样我们用index保存小数点前面不为0的数字的位置,同样的让r初始化为"0."然后再移除小数点(移到前面去了),将index后面n位子字符串拼接到r的后面,如果该子字符串的长度s.size()-index,要在后面补0,最后再添加指数部分,指数的次幂为pos-index(pos-index为小数点前面不为0数字的个数,也就是小数点移动的位数)

注意点:

1、数字签名可能会有前导0,比如000 000.12 00004522145.155,测试点2,4,6考察,处理方法可以采取去除前导0,这里是直接归类于第二类,然后会跳转到第一类,直接处理小数点后面的数字即可。
2、对于000.00的情况需要输出0.@@@(n个@)*10^0,测试点6考察。
3、对于整数的处理,这里采用在最后添加一个小数点归纳在第二类中。
4、对于本身不需要移动小数点的情况,除了000.00这样的需要在最后添加10^0外,其他的点没有考察,也就是像0.12保留2位数字输出0.12和0.12*10^0都是可以的。

提交结果:

PAT_甲级_1060 Are They Equal_第1张图片

测试数据:

4 0000 0000.00 //YES 0.0000$*$10^0
4 00123.5678 0001235 //NO 0.1235$*$10^3 0.1235$*$10^4
3 0.0520 0.0521 // NO 0.520$*$10^-1 0.521$*$10^-1
4 00000.000000123 0.0000001230 // YES 0.1230$*$10^-6
4 00100.00000012 100.00000013 // YES 0.1000$*$10^3
5 0010.013 10.012 // NO 0.10013$*$10^2 0.10012$*$10^2
4 123.5678 123.5 // YES 0.1235$*$10^3
3 123.5678 123 // YES 0.123$*$10^3
4 123.0678 123 // YES 0.1230$*$10^3
3 0.000 0 // YES 0.000$*$10^0

AC代码:

#include
#include

using namespace std;

string type1(string s,int n,int pos){//处理形式0.*****的字符串
    string r = "0.";//保存最后结果 
    int index;//保存小数点后面第一个不为0的位置 
    for(index=pos+1;index

你可能感兴趣的:(算法-数据结构,c++)