以一種更自然的方式去思考

2021-06-16 07:13:22 字數 2452 閱讀 2603

usaco 2.4.5《fractions to decimals》困擾了我很久,並不是題目本身有多難,而是之前的演算法是一種不太自然的方式建立的,順著演算法的思路得到的答案總是若隱若現——有時候正確,有時候又會出現類似於錯位的小錯誤。而我這個人又比較懶,不太願意徹底去改變自認為已經考慮清楚的演算法,而更多的是從小處著眼,增強程式的適應能力,這種改法往往治標不治本,最後的結果是讓自己的思路變得很凌亂。

實驗室原定今天下午的例會取消,我終於可以放下一直糾結於心的soa,進入久違的usaco training。首先入手就是上次沒有解決的《fractions to decimals》,上次的程式除錯了很長時間,已經通過了5組資料,在第6組資料的時候卡住了,錯誤有點莫名奇妙。我決定放棄原來的**,重新整理思路。

寫乙個程式,輸入乙個形如n/d的分數(n是分子,d是分母),輸出它的小數形式。如果小數有迴圈節的話,把迴圈節放在一對圓括號中。

例如, 1/3 =0.33333333 寫成0.(3), 41/333 = 0.123123123... 寫成0.(123), 用***.0 等表示整數。典型的轉化例子:

1/3 = 0.(3)

22/5 = 4.4

1/7 = 0.(142857)

2/2 = 1.0

3/8 = 0.375

45/56 = 0.803(571428)

1.       整數。例如2/2【1.0】

2.       非迴圈小數。例如22/5【4.4】

3.       迴圈小數,迴圈節從小數點後第一位開始。例如1/7【0.(142857)】

4.       迴圈小數,迴圈節從小數點後第一位開始。例如45/56【0.803(571428)】

在稿紙上重新演算了45/56的整體過程。重新定義演算法:

先讀入並列印整書部分。接下來,對剩下的真分數部分進行長除直到我們發現了重複的餘數或餘數變為0。如果我們發現了重複的餘數,即出現了迴圈節,就分別恰當地列印重複的部分和不重複的部分。如果餘數變為0,即已經除盡,就列印整個小數部分。如果小數字根本沒有生成,那麼就列印乙個0就是是正確答案了。

由於最後的輸出有格式要求,我們從一開始將整數以及小數的餘數部分儲存起來,到最後統一輸出。

id:lichaoy2

task:fracdec

lang:c++

#include

#include

#include

#include

using namespace std;

#define maxn 100000

int main()

int n,d,i,k,t;

int remainder[maxn];

vectordigit;

//餘數初始化

for (i=0; iremainder[i] = -1;

ifstream fin("fracdec.in");

//輸入

fin>> n >> d;

fin.close();

//找到小數點前的部分

t = n/d;

k= n%d;

remainder[0]=0;

//計算小數點後的部分

for (; ; )

if (remainder[k] >= 0)

break;

digit.push_back(k);

remainder[k] = k*10/d;

k = (k*10)%d;

ofstream fout("fracdec.out");

char str[maxn];

sprintf(str,"%d",t);

fout << str << ".";

if (k==0)//如果是整除

if (digit.size() == 0)

fout << "0";

for (i=0; iif ((strlen(str)+1+i)%76==0)

fout << endl;

fout << remainder[digit[i]];

fout << endl;

else

for (i=0; digit[i] != k; ++i)

if ((strlen(str)+1+i)%76==0)

fout << endl;

fout << remainder[digit[i]];

//輸出迴圈節

fout << "(";

for (;iif ((strlen(str)+2+i)%76==0)

fout << endl;

fout << remainder[digit[i]];

if ((strlen(str)+2+i)%76==0)

fout << endl;

fout << ")"return 0;

這題給我的啟示是:遇到題目要以一種更加自然的方式去思考,找到最容易理解的解決方案,這樣排錯和除錯都會更加方便。

一種很好的思考方式

思考方式 當你拿到某個 技術點 或是遇到某個什麼所謂的 技巧 甚至是工具 之後,該如何進一步展開學習思考?如下 這tm 到底是個什麼東西?正常情況下 它都被用在什麼地方?平時主要拿它來幹啥?或者說這個東西可以協助解決一些什麼樣的實際業務問題 它在 正常情況下 具體是怎麼運作的 或者說其內部大致 實現...

數學是一種思考方式

這幾天有個讀者來來去去給我寫了幾封 email 問起我的觀點 數學和程式設計是什麼關係?學程式設計需要多深的數學基礎?到底需要掌握哪些數學知識,對程式設計能力的提高有幫助。這個還真不好說。如果說起課堂上我們學到的知識。除了初等代數,在程式設計中我還真沒碰到多少依賴數學技能來解決的問題。當年我學 c ...

數學是一種思考方式

這幾天有個讀者來來去去給我寫了幾封 email 問起我的觀點 數學和程式設計是什麼關係?學程式設計需要多深的數學基礎?到底需要掌握哪些數學知識,對程式設計能力的提高有幫助。這個還真不好說。如果說起課堂上我們學到的知識。除了初等代數,在程式設計中我還真沒碰到多少依賴數學技能來解決的問題。當年我學 c ...