CF691C Exponential notation

· · 题解

原题:CF691C Exponential notation。

非常经典的一道题目。

思路

本题为数学题,主要考察写题的能力。

如果写不好,本体很容易 TLE。

首先,我们需要知道,科学计数法的表示方式。

举个例子:3.14\times10^5 = 314000

我们将 314000 的小数点标出来,为 314000.0,我们在科学计数法中,小数点在 314 之间,我们在 314000.0314 之间也加入小数点,为 3.14000.0,发现两个小数点之间正好五位数字,而 314000 恰好等于 3.14\times 10^5,多测试几个数字,手算一下,易发现两点之间的数字数目和指数是相同的。

我们只要判断小数点应该加在哪里,然后计算两个小数点之间的数字数目即可。

另外要注意的是 前导零和后倒零要去掉,如果指数为 0,则不要输出 E0

代码

#include <bits/stdc++.h>

#pragma g++ optimize(2)
#pragma g++ optimize(3)
#pragma g++ optimize("inline")
#pragma g++ optimize("Ofast")

using namespace std;

#define ll long long
#define ull unsigned long long
#define s(v) (int)v.size()

const int mod=998244353,N=1000005,INF=1<<30;

bool q[N],h[N];

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  string s;
  cin>>s;
  int len=s(s);
  bool flg=0;
  for(int i=0;i<len;++i) if(s[i]=='.') {flg=1;break;}
  if(!flg) s+='.',len++;
  int tpa,tpb;
  for(int i=len-1;i>=0;--i) h[i]=h[i+1]|(s[i]!='0'&&s[i]!='.');
  flg=1;
  for(int i=0;i<len;++i) {
    if(s[i]=='.') {tpa=i;continue;}
    else if(flg&&s[i]!='0') flg=0,tpb=i+1;
    if(s[i]=='0'&&flg==1) continue;
    if(h[i]) {
        cout<<s[i];
        if(i==tpb-1&&h[i+1]) cout<<'.';
    }
  }
  int tt=(tpa>=tpb)?tpa-tpb:tpa-tpb+1;
  if(tt!=0) cout<<"E"<<tt;
  return 0;
}

我的 AC 记录。