原题链接 这道题真的值得好好品 从思路再到细节处理都挺妙的 特别注意点:会有前导0 思路 一、考虑数据本身 可以分为两种情况 第一种:0.a1a2a3… 第二种:b1b2b3…bm . a1a2a3 二、考虑两种情况的主体与指数部分 综上,整个过程可以分为三大部分 1.去除前导0 (考虑到前导零存在的情况 经过此步骤以后 根据字符串首位是否为‘.’便可以区分为第一种情况还是第二种情况了) 2. 初步构造字符串(首字符大于0且不含小数点)也是寻找小数点删除小数点的过程这个过程中还需要确定指数 第一种数据情况:指数为‘.’到第一位正数 记得计数完最后取反 第二种数据情况:指数为第一位正数到‘.’的个数
寻找小数点中用K记录 如果k<s.length() 说明找到了小数点 做完所有工作后 如果s.length()=0说明字符串初始为0或0.00之类 3.对剩余字符res串进行加工构造符合题意的结果 因为考虑到最后的s可能位数不到n位,可以采用将s添加到res这个空字符串中去 长就取n位字符不够就补‘0’
int num = 0,k = 0; string res; while(num < n) { if(k < s.length()) res = res+s[k++]; else res += ‘0’; num ++; }
#include <iostream> #include <cstdio> #include <string> using namespace std; string deal (string s, int &e ,int n) //需要处理的字符串s 记录指数 接收有效位数 { //由数据类型可以分为两种 //一、0.a1a2a3a4 //二、b1b2..bm.a1a2a3 //第一步删除前置0 通过留下第一位是否是.来判断为第一种情况还是第二种情况 while(s.length()>0&&s[0] == '0') //第一大部分工作 :去除前导零 { s.erase(s.begin()); } //第二大部分工作 去除小数点 if(s[0] == '.') //这时是第一种情况 需要找到第一位正整数 并且记录指数个数 记得取反 { s.erase(s.begin()); //删除小数点 while(s.length()>0&&s[0]=='0') { e++; s.erase(s.begin()); } e = (-1)*e; } else //第二种情况 找小数点删去小数点 { int k=0;//记录小数点位数 while(k < s.length()&&s[k]!='.') //开始寻找小数点 但可能找得到也可能找不到因此又会分为两种情况 { e++;// 记录指数 k++; } 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) { if(k < s.length()) res = res+s[k++]; else res += '0'; num ++; } return res; } int main() { int n; string str1,str2,str3,str4; int e1=0,e2=0; cin>>n>>str1>>str2; str3=deal(str1,e1,n); str4=deal(str2,e2,n); if(str3==str4&&e1==e2) { cout<<"YES 0."<<str3<<"*10^"<<e1<<endl; } else { cout<<"NO 0."<<str3<<"*10^"<<e1<<" 0."<<str4<<"*10^"<<e2<<endl; } return 0; }