洛谷 U140098 計數
洛谷傳送門
題目背景
從古到今,人類的計數方式有着顯著的進步。
追溯到五千年到八千年前,這時,四大文明古國都早已從母系社會過渡到父系社會了,生産力的發展導緻國家雛形的産生,生産規模的擴大則刺激了人們對大數的需要。比如某個原始國家組織了一支部隊,國王陛下總不能老是說:“我的這支戰無不勝的部隊共計有9名士兵!”于是,慢慢地就出現了“十”、“百”、“千”、“萬”這些符号。在我國商代的甲骨文上就有“八日辛亥允戈伐二千六百五十六人”的刻文:即在八日辛亥那天消滅敵人共計2656人。在商周的青銅器上也刻有一些大的數字,以後又出現了“億”、“兆”這樣的大數機關。
而在古羅馬,最大的記數機關隻有“千”.他們用M表示一千.“三千”則寫成“MMM”.“一萬”就得寫成“MMMMMMMMMM”。難以想象,如果他們需要記一千萬時怎麼辦,難道要寫上一萬個M不成?
總之,人們為了尋找記大數的機關是花了不少腦筋的。舊社會在農村讀私塾,一些私塾先生會教:“最大的數叫‘猴子翻跟鬥’”。這位私塾先生可能認為孫悟空一個跟鬥翻過去的路程是最最遠的,不能再遠了,是以完全可以用“猴子翻跟鬥”來表示最大的數。在古印度,使用了一系列大數機關後,最後的最大的數的機關叫做“恒河沙”.是呀,恒河中的沙子誰數得清!
然而,古希臘有一位偉大的學者,他卻數清了“充滿宇宙的沙子數”,那就是阿基米德.他寫了一篇論文,叫做《計沙法》。在這篇文章中,他提出的記數方法,同現代數學中表示大數的方法很類似。他從古希臘的最大數字機關“萬”開始,引進新數“萬萬(億)”作為第二階機關,然後是“億億”(第三階機關),“億億億”(第四階機關),等等,每階機關都是它前一階機關的1億倍。阿基米德的同時代人、天文學家阿裡斯塔克斯曾求出地球到天球面距離10,000,000,00010,000,000,000斯塔迪姆(11斯塔迪姆=188=188米)。這個距離當然比現在我們所認識的宇宙要小得多,這才僅僅是太陽到土星的距離。阿基米德假定這個“宇宙”裡充滿了沙子.然後開始計算這些沙子的數目。最後他寫道:“顯然,在阿裡斯塔克斯計算出的天球裡所能裝入的沙子的粒數,不會超過一千萬個第八階機關”。如果要把這個沙子的數目寫出來,就是10,000,000×(100,000,000)_710,000,000×(100,000,000)7或者就得在11後邊寫上6363個00:1,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,0001,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000。這個數,我們現在可以把它寫得簡單一些:即寫成1×10^{63}1×1063。而這種簡單的寫法,據說是印度某個不知名的數學家發明的。這種用在11與1010間的一個數乘以1010的若幹次幂的記數方法就是“科學記數法”。
用科學記數法表示數時,不改變數的符号,隻是改變數的書寫形式而已,可以友善的表示日常生活中遇到的一些極大或極小的數。
如:光的速度大約是300,000,000300,000,000米/秒;全世界人口數大約是:6,100,000,0006,100,000,000.
這樣的數,讀、寫都很不友善,我們可以免去寫這麼多重複的00,将其表現為這樣的形式:
6,100,000,000=6.1×10^96,100,000,000=6.1×109
或:
0.00001=1×10^{-5}0.00001=1×10−5
即絕對值小于1的數也可以用科學記數法表示為aa乘1010的負nn次方的形式。
題目描述
雖然科學記數法是國小四年級的數學知識。但是為了紀念出題人在CSP-S2020CSP−S2020的考場上被坐在身旁的國小生反複敲打,現将科學記數法的記法向選手叙述。對于不同選手可能存在的對科學計數法的認知差别,皆以本叙述為準:
對于一個數xx:
1、若|x|>1∣x∣>1,則記為a\times 10n*a*×10*n*的形式。n*n*的值由x*x*的位數決定,設m*m*為x*x*的位數,則n=m-1*n*=*m*−1,a=\frac{x}{10n}a=10n**x。
2、若|x|<1∣x∣<1,則n=-(m-m_1),a=x\times 10^{m-m_1}n=−(m−m1),a=x×10m−m1,其中mm為xx的位數,m_1m1為xx的有效數位。
與此同時,在計算數學中,數學家們引入了新的符号EE以代替這種1010的整數次幂的表示形式。具體地,有:
1、a\times 10^n=aEna×10n=aEn。
2、特别地,當n=0n=0時,省略E0E0。
根據以上規律,編寫程式,解決“給出一個合法的十進制數,求其科學記數法表示”這類問題是很容易的。我們當下面臨的問題是:不保證給出的十進制數合法。具體地,有:
1、可能出現若幹前置0。
2、可能出現若幹後置0。
3、小數點可以單獨出現而不需要前字尾。即:.612.612和914.914.這類數都是有可能出現的。
那麼,現在給你一個長度為NN的、符合以上要求的數字,請你按以上要求編寫程式,求出其正确的科學計數法表示。
輸入格式
從檔案count.incount.i**n中讀入資料。
一行一個長度為NN的字元串,描述一個待轉換的數字。
輸出格式
輸出到檔案count.outcount.out中。
一行一個字元串,表示這個數字的合法科學計數法表示。
命題背景:
為了紀念CSP-S2020 T1挂分,特意出了這道題來訓練選手的審題及對各種複雜資料的調試能力。
也就是從廢話連篇的題面中提取關鍵資訊。但是說實在的,這套題出的還是有些不好,因為前面的真的就是純廢話,中間一點有價值的東西都沒有,是以不看也罷。
但是拿這玩意搞搞選手心态練練選手心理素質,并且練練碼力,我覺得也是不錯的啊。
是以還是有很大價值的。
題解:
解法不唯一,依照題意模拟即可。
加入了很多hack資料來細節。
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e6+6;
char ori[maxn];
bool flag;
int main()
{
scanf("%s",ori+1);
int len=strlen(ori+1);
int l=1,r=len;
int ppos=0;
if(len==1)
{
printf("%c\n",ori[l]);
return 0;
}
while(ori[l]=='0')
l++;
if(ori[r]=='.')
r--;
for(int i=l;i<=r;i++)
if(ori[i]=='.')
{
ppos=i;
flag=1;
break;
}
if(ppos==len)
flag=0;
if(ppos==l)
{
l++;
while(ori[r]=='0')
r--;
if(ori[r]=='.')
r--;
while(ori[l]=='0')
l++;
int cnt=0;
while(cnt<=r-l)
{
if(cnt==1)
printf(".");
printf("%c",ori[l+cnt]);
cnt++;
}
printf("E%d\n",-(l-ppos));
return 0;
}
else if(flag==1)
{
while(ori[r]=='0')
r--;
if(ori[r]=='.')
r--;
while(ori[r]=='0')
r--;
int cnt=0;
while(cnt<=r-l)
{
if(cnt==1)
printf(".");
if(ori[l+cnt]=='.')
{
cnt++;
continue;
}
printf("%c",ori[l+cnt]);
cnt++;
}
if(ppos-l-1==0)
return 0;
printf("E%d\n",ppos-l-1);
return 0;
}
else if(flag==0)
{
if(l==r)
{
printf("%c",ori[l]);
return 0;
}
int cnt=0;
int zhi=r-l;
while(ori[r]=='0')
r--;
while(cnt<=r-l)
{
if(cnt==1)
printf(".");
printf("%c",ori[l+cnt]);
cnt++;
}
printf("E%d\n",zhi);
return 0;
}
return 0;
}