PAT-ADVANCED1060——Are They Equal

我的PAT-ADVANCED代码仓:https://github.com/617076674/PAT-ADVANCED

原题链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805413520719872

题目描述:

题目翻译:

1060 它们是否相等

如果机器只能保存3位有效数字,则浮点数12300和12358.9被认为是相等的,因为它们都保存为0.123×10 ^ 5。现在给出一台机器上的有效位数和两个浮点数,你需要指出它们在该机器中是否被视为相等。

输入格式:

每个输入文件包含一个测试用例,它给出三个数字N,A和B,其中N(<100)是有效位数,A和B是要比较的两个浮点数。 每个浮点数都是非负数,不大于10 ^ 100,即总位数小于100。

输出格式:

对于每个测试用例,如果两个数字处理相等,则在一行中打印“Yes”,然后以标准形式编号为0.d [1] ... d [N] * 10 ^ k(d [1]> 0 除非数字是0);如果相等,则输出“NO”,然后是标准形式的两个数字。 所有数字由一个空格分隔,一行末尾没有多余空格。

注意:不考虑四舍五入。

输入样例1:

3 12300 12358.9

输出样例1:

YES 0.123*10^5

输入样例2:

3 120 128

输出样例2:

NO 0.120*10^3 0.128*10^3

知识点:字符串

思路:按整数部分是否为0来分情况讨论

先写几个坑点:

(1)题目的数字可能有前导0,即00123这种形式。

(2)题目中的数字可能出现0.000、1.000这种形式。

(3)即使指数是0,也要写出来。

(4)指数可以是负数,也就是说对于0.000012的情况,其结果不应该是0.000,而应该是0.120 * 10 ^ -4次。

题目的要求是将两个数改写为科学计数法的形式,然后判断它们是否相等。而科学计数法的写法一定是如下格式:0.a1a2a3... * 10 ^ e,因此只需要获取到科学计数法的本体部分a1a2a3指数e,即可判定两个数在科学计数法形式下是否相等。

按整数部分是否为0来分情况讨论,即

(1)0.a1a2a3...

(2)b1b2...bm.a1a2a3...

现在来考虑这两种情况的本体部分与指数分别是什么(以下讨论均按有效位数为3进行)。对(1)来说,由于在小数点后面还可能跟着若干个0,因此本体部分是从小数点后第一个非零位开始的3位(即akak + 1ak + 2,其中ak是小数点后第一个非零位),而指数则是小数点与该非零位之间0的个数的相反数(例如0.001的指数为-2)。在分析清楚后,具体的代码实现逻辑也就成形了,即令指数e的初值为0,然后在小数点后每出现一个0,就让e减1,直到到达最后一位(因为有可能是小数点后全为0的情况)或是出现非零位为止。

然后来看(2)的情况,假设b1不为零。很显然,其本体部分就是从b1开始的3位,而指数则是小数点前的总位数m。具体实现中,则可以令指数e的初值为0,然后从前往后枚举,只要不到达最后一位(因为有可能没有小数点)或是出现小数点,就让e加1。

如何区分给定的数是(1)还是(2)呢?先去除所有的前导0,按去除前导0后的字符串的第一位是否是小数点来判断其属于(1)或是(2)。

由于需要让两个数的科学计数法进行比较,因此必须将各自的本体部分单独提取出来。比较合适的方法是,在按上面的步骤处理(1)时,将前导0、小数点、第一个非零位前的0全部删除,只保留第一个非零位开始的部分(即akak + 1ak + 2...)。在处理(2)时,将前导0、小数点删除,保留从b1开始的部分(即b1b2...bma1a2a3...)。这些删除操作可以在上面获取指数e的过程中同时做到(使用string的erase函数)。之后便可以对剩余的部分取其有效位数的部分赋值到新字符串中,长度不够有效位数则在后面补0。

最后只要比较本体部分和指数是否都相等,就可以决定输出“YES”或“NO”。

时间复杂度和空间复杂度的分析对本题来说意义不大。

C++代码:

#include<iostream>
#include<string>

using namespace std;

int n;	//有效位数

string deal(string s, int &e);

int main(){
	string s1, s2, s3, s4;
	cin >> n >> s1 >> s2;
	int e1 = 0, e2 = 0;	//e1,e2为s1与s2的指数
	s3 = deal(s1, e1);
	s4 = deal(s2, e2);
	if(s3 == s4 && e1 == e2){
		cout << "YES 0." << s3 << "*10^" << e1 << endl;
	}else{
		cout << "NO 0." << s3 << "*10^" << e1 << " 0." << s4 << "*10^" << e2 << endl;
	}
}

string deal(string s, int &e) {
	int k = 0;	//s的下标
	while(s.length() > 0 && s[0] == '0') {
		s.erase(s.begin());	//去掉s的前导零
	}
	if(s[0] == '.') {	//去掉前导零后是小数点,说明s是小于1的小数
		s.erase(s.begin());	//去掉小数点
		while(s.length() > 0 && s[0] == '0') {
			s.erase(s.begin());	//去掉小数点后非零位前的所有零
			e--; //每去掉一个0,指数e减1
		}
	} else {	//去掉前导零后不是小数点,则找到后面的小数点删除
		while(k < s.length() && s[k] != '.') {	//寻找小数点
			k++;
			e++;	//只要不碰到小数点就让指数e++
		}
		if(k < s.length()) {
			s.erase(s.begin() + k);	//把小数点删除
		}
	}
	if(s.length() == 0) {	//如果去除前导零后s的长度变为0,说明这个数是0
		e = 0;
	}
	int num = 0;
	k = 0;
	string res;
	while(num < n){	//只要精度还没有到n 
		if(k < s.length()){
			res += s[k++];
		}else{
			res += '0';
		}
		num++;
	}
	return res;
}

C++解题报告:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
城市应急指挥系统是智慧城市建设的重要组成部分,旨在提高城市对突发事件的预防和处置能力。系统背景源于自然灾害和事故灾难频发,如汶川地震和日本大地震等,这些事件造成了巨大的人员伤亡和财产损失。随着城市化进程的加快,应急信息化建设面临信息资源分散、管理标准不统一等问题,需要通过统筹管理和技术创新来解决。 系统的设计思路是通过先进的技术手段,如物联网、射频识别、卫星定位等,构建一个具有强大信息感知和通信能力的网络和平台。这将促进不同部门和层次之间的信息共享、交流和整合,提高城市资源的利用效率,满足城市对各种信息的获取和使用需求。在“十二五”期间,应急信息化工作将依托这些技术,实现动态监控、风险管理、预警以及统一指挥调度。 应急指挥系统的建设目标是实现快速有效的应对各种突发事件,保障人民生命财产安全,减少社会危害和经济损失。系统将包括预测预警、模拟演练、辅助决策、态势分析等功能,以及应急值守、预案管理、GIS应用等基本应用。此外,还包括支撑平台的建设,如接警中心、视频会议、统一通信等基础设施。 系统的实施将涉及到应急网络建设、应急指挥、视频监控、卫星通信等多个方面。通过高度集成的系统,建立统一的信息接收和处理平台,实现多渠道接入和融合指挥调度。此外,还包括应急指挥中心基础平台建设、固定和移动应急指挥通信系统建设,以及应急队伍建设,确保能够迅速响应并有效处置各类突发事件。 项目的意义在于,它不仅是提升灾害监测预报水平和预警能力的重要科技支撑,也是实现预防和减轻重大灾害和事故损失的关键。通过实施城市应急指挥系统,可以加强社会管理和公共服务,构建和谐社会,为打造平安城市提供坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值