PAT (Advanced Level) Practice 1060 Are They Equal (25 分) 凌宸1642

PAT (Advanced Level) Practice 1060 Are They Equal (25 分) 凌宸1642

题目描述:

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.

译:如果一台机器只能保存 3 位有效数字,浮点数 12300 和 12358.9 被认为是相等的,因为它们都通过简单的斩波保存为 0.123×105。 现在给定一台机器上的有效位数和两个浮点数,您应该判断它们在该机器中是否被同等对待。


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.

译:每个输入文件包含一个测试用例,给出三个数字 N、A 和 B,其中 N (<100) 是有效位数,A 和 B 是要比较的两个浮点数。 每个浮点数为非负数,不大于10100,总位数小于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.

译:对于每个测试用例,如果两个数被视为相等,则在一行中打印 YES,然后以标准形式 0.d[1]...d[N]*10^k (d[1]>0 除非数字是0); 或者 NO 如果它们不被平等对待,然后是标准形式的两个数字。 所有术语必须用空格分隔,行尾不能有多余的空格。

注意:假设没有四舍五入的简单斩波。


Sample Input1 (样例输入1):

3 12300 12358.9

Sample Output1 (样例输出1):

YES 0.123*10^5

Sample Input2 (样例输入2):

3 120 128

Sample Output2 (样例输出2):

NO 0.120*10^3 0.128*10^3

The Idea:

题目意思描述的就是简单的科学计数法保留 N 位有效数字问题。首先按照正常人的思维,假设所有的输入都是符合我们的常识的好输入时,测试点4和测试点6是过不了的,最后思考再三,想到了是不是因为测试数据中存在前导0的数据,比如00123 , 00.001这种数据,所以在输入之后,先进行去除前导 0 操作。然后测试点4过了, 测试点6依旧没过。这时候看题意,输入了测试数据0 0 0.000 ,好家伙,果然输出了 NO , 所以测试点6应该就是对输入 0 的特判了。

The Codes:

#include<bits/stdc++.h>
using namespace std ;
typedef pair<string , int> PSI ;
string a , b ;
int n ;
PSI deal(string s) {
	string res = "0." ;
	int exp = 0 ;
	if( s.find(".") == string::npos){ // 整数,不存在小数点 
		exp = s.size() ;
		if(exp >= n){   // 有效数字位数 >= 能够保存的位数 
			res += s.substr(0 , n) ;  // 需要截断 
		}else{  // 有效数字位数 < 能够保存的位数 
			res += s ; 	// 拼接所有的有效数字后 
			for(int j = exp ; j < n ; j ++) res += "0" ;  // 末尾补 0 
			if(s.size() == 1 && s[0] == '0') exp = 0 ; 	// 如果是整数 0 ,特判一下
		}
	}else{
		if(s[0] == '0'){  // 是 0.xxxxx   形态
			int i = 2 ;
			for( ; i < s.size() ; i ++) if(s[i] != '0') break ;
			if(i != s.size()){
				exp = 2 - i ;
				int l = s.size() - i ;
				if(l >= n) res += s.substr(i , n) ;
				else{
					res += s.substr(i , l) ;
					for(int j = l ; j < n ; j ++) res += "0" ;  // 末尾补 0 
				}
			}else{ // s 是 0.000···000
				exp = 0 ;
				for(int j = 0 ; j < n ; j ++) res += "0" ;  // 全是 0 
			}
		}else{
			exp = s.find(".") ;
			if(exp >= n) res += s.substr(0 , n) ;  // 需要截断 
			else if(s.size() - 1 >= n){
				res += s.substr(0 , exp) ; // 拼接小数点前的 exp 位 
				res += s.substr(exp + 1 , n - exp ) ; // 拼接小数点前的 n - exp 位 
			}else{
				res += s.substr(0 , exp) ; 	// 拼接小数点前的 exp 位 
				res += s.substr(exp + 1 , s.size() - exp - 1) ; // 拼接小数点前的 size() - exp - 1 位 
				for(int i = s.size() - 1 ; i < n ; i ++) res += "0" ;  // 末尾补 0 
			}
		}
		
	} 
	return make_pair(res , exp) ;
}
string delPre0(string s) {
	int i = 0 ;
	for(; i < s.size() - 1 ; i ++){
		if(s[i] =='0' && s[i+1] == '0') continue ;
		else break ;
	}
	if(s[i + 1] != '.') return s.substr(i + 1 , s.size() - i - 1) ;
	return s.substr(i  , s.size() - i ) ;
}
int main(){
	cin >> n >> a >> b ;
	if(a[0] == '0')a = delPre0(a) ;
	if(b[0] == '0')b = delPre0(b) ;
	PSI psia = deal(a) ;
	PSI psib = deal(b) ;
	if(psia.first == psib.first && psia.second == psib.second)
		printf("YES %s*10^%d\n" , psia.first.c_str() , psia.second );
	else
		printf("NO %s*10^%d %s*10^%d\n" , psia.first.c_str() , psia.second , psib.first.c_str() , psib.second) ;
	return 0 ;
}

posted @ 2021-08-11 00:07  凌宸1642  阅读(47)  评论(0)    收藏  举报