最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

C++信息學(xué)競(jìng)賽例題解析——高精度加法

2020-11-06 23:00 作者:非知名科技區(qū)UP  | 我要投稿

近期呢,我們剛學(xué)了C++中string字符串的基礎(chǔ)與應(yīng)用。string字符串的一大好處就是輸入的格式?jīng)]有限制,長(zhǎng)度不限。并且相較于C語(yǔ)言的char,總體而言方便了不少。當(dāng)數(shù)據(jù)大小可能超過(guò)long long int的數(shù)據(jù)范圍或者小數(shù)后面的位數(shù)超過(guò)雙精度浮點(diǎn)數(shù)的時(shí)候,通過(guò)字符串實(shí)現(xiàn)的“高精度”計(jì)算就是一個(gè)很好的解決方案。在我們做真正的競(jìng)賽題時(shí),可能會(huì)遇到超大的輸入數(shù)據(jù)規(guī)模,這時(shí)候使用這種高精度數(shù)據(jù)的計(jì)算就變得很有必要。

我們這次作業(yè)中另一道題的數(shù)據(jù)規(guī)模,注意被除數(shù)是長(zhǎng)度不超過(guò)30萬(wàn)位!!

歷經(jīng)本UP主3天3夜的思考+爆肝,我終于弄明白了這樣的一道題的解法。

題目源自我們學(xué)校的信息競(jìng)賽題庫(kù)——BNDSOJ,網(wǎng)址124.205.120.153

我的解決方案:

實(shí)際上這個(gè)題的難點(diǎn)有這么幾個(gè):

  1. 要讓你的程序判定輸入數(shù)據(jù)是否有小數(shù)點(diǎn)并且做出相應(yīng)反饋。

  2. 要把小數(shù)和整數(shù)分開(kāi)計(jì)算,但是小數(shù)到整數(shù)的進(jìn)位問(wèn)題是不可以忽視的。

  3. 根據(jù)我個(gè)人的習(xí)慣以及節(jié)約時(shí)間的原則,我會(huì)把計(jì)算用的數(shù)組給提前開(kāi)辟好,在主程序開(kāi)始前將需要的內(nèi)存空間申請(qǐng)下來(lái)。但是再輸出的時(shí)候我需要保證不輸出多余的“0”

  4. 小數(shù)中的十分位進(jìn)位到個(gè)位是一大難點(diǎn)。

我的程序詳解


#include <iostream>
#include <string>
#include <cstring>

using namespace std;
【5】 bool ata = false,atb = false;
??string pa,pb,pc;
???int y = 0;
??bool sta = false,jin = false;
?int sn[40],ln[40];
【10】int main(){
?cin >> pa >> pb;//最基本的,聲明數(shù)組和數(shù)據(jù)輸入
?if(pa.find('.')==-1){
??ata = true;
???}??
【15】if(pb.find('.')==-1){?
??atb = true; //確定輸入的數(shù)據(jù)中有無(wú)整數(shù)
??}

?int sc[40][2],lc[40][2];
?int x = 0;
【20】 memset (sc,0,sizeof sc);
?memset (lc,0,sizeof lc);//清空用于計(jì)算的數(shù)組

? int g =pa.find('.'),h=pb.find('.');
?if(ata ==true)
?g = pa.size();
【25】if(atb == true)
?h = pb.size();//確定小數(shù)點(diǎn)在string數(shù)組中的位置

程序至此就算完成了基本的數(shù)據(jù)情況的設(shè)置,接下來(lái),就是核心的計(jì)算環(huán)節(jié)了。

for(int a=g,b=h;a<=pa.size()||b<=pb.size();a++,b++,x++){
??if(pa[a]>='0'&&pa[a]<='9')
??sc[x][0]=pa[a]-'0';
?【30】 if(pb[b]>='0'&&pb[b]<='9')
??sc[x][1]=pb[b]-'0';?? ?????????''
???}

??memset (lc,0,sizeof lc);
?int a =pa.find('.'),b=pb.find('.');
?【35】if(ata ==true)
?a = pa.size();
?if(atb == true)
?b = pb.size();
?for( ;a>=0||b>=0;a--,b--,y++){
?【40】 if(pa[a]>='0'&&pa[a]<='9')
??lc [y][0]=pa[a]-'0';
??if(pb[b]>='0'&&pb[b]<='9')
??lc[y][1]=pb[b]-'0';
???}

//上面的環(huán)節(jié)是將字符串形式的數(shù)據(jù)轉(zhuǎn)化成便于進(jìn)行計(jì)算加工的數(shù)組形式。先轉(zhuǎn)化的是小數(shù)部分,然后是整數(shù)部分。兩個(gè)部分分別存放在兩個(gè)不同的二維數(shù)組里,準(zhǔn)備運(yùn)算。
?【45】for(int z = 39;z>=0;z--){
??sn[z]=(sc[z][0]+sc[z][1])%10;
??sc[z-1][0]=sc[z-1][0]+((sc[z][0]+sc[z][1])/10);
???}
?if(sn[0]==1){
?【50】jin=true;//bool變量“ jin”反應(yīng)的是小數(shù)是否需要進(jìn)位到整數(shù)
?lc[0][0]=lc[0][0]+1;}
??for(int z = 0;z<=39;z++){
???if(jin==true&&z==0){
????ln[z]=ln[z]+((lc[z][0]+lc[z][1])%10);
?【55】 lc[z+1][0]=lc[z+1][0]+((lc[z][0]+lc[z][1])+1/10);
?????}
??else{
??ln[z]=(lc[z][0]+lc[z][1])%10;
?lc[z+1][0]=lc[z+1][0]+((lc[z][0]+lc[z][1])/10);}
?【60】 }

這里是最中心的運(yùn)算環(huán)節(jié)。記住我們應(yīng)該從最小的一位算起,先算小數(shù),再看是否需要進(jìn)位,再算整數(shù)。此時(shí)答案已經(jīng)被存儲(chǔ)在in和sn兩個(gè)數(shù)組里了。

最后的輸出環(huán)節(jié)中,兩個(gè)數(shù)組分別需要用不同的辦法排除數(shù)組里多余的“0”,然后判斷是否需要輸出小數(shù)點(diǎn)以及后面的數(shù)。

for(int z = 30;z>0;z--){
??if(ln[z]!=0)
??sta = true;
??if(sta == true)
??cout << ln[z];
???}
?if(sta==false)
?cout <<"0"; //輸出整數(shù)的部分

?int j = 29;
while(j>0&&sn[j]==0){
?j = j -1; }//通過(guò)一個(gè)while循環(huán)來(lái)確定輸出多少位小數(shù)

if(j)
cout << ".";//確定輸出小數(shù)點(diǎn)

?for(int a = 1;a<=j;a++){
??cout <<sn[a];
???}//輸出小數(shù),程序結(jié)束。
?return 0; }

由于本題中給的數(shù)據(jù)規(guī)模較小,我可以將程序?qū)懙南鄬?duì)復(fù)雜。但為了貫徹“節(jié)約每一毫秒的運(yùn)行時(shí)間”的原則,我將數(shù)組和各類變量、string字符串的申請(qǐng)放到了主程序開(kāi)始之前——這樣測(cè)評(píng)機(jī)就不會(huì)將調(diào)用內(nèi)存空間的時(shí)間計(jì)入運(yùn)行時(shí)間內(nèi)。



C++信息學(xué)競(jìng)賽例題解析——高精度加法的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
繁昌县| 象山县| 璧山县| 奈曼旗| 土默特右旗| 海丰县| 突泉县| 新竹市| 盖州市| 昂仁县| 隆回县| 贵溪市| 西林县| 吉隆县| 台南县| 塔城市| 社会| 澳门| 徐闻县| 淮北市| 乐都县| 平远县| 志丹县| 芒康县| 鞍山市| 当阳市| 泉州市| 克东县| 水富县| 尼木县| 莒南县| 那坡县| 嵊泗县| 梅州市| 仲巴县| 西华县| 亚东县| 肇东市| 蓬安县| 北海市| 萨迦县|