Upload
vevina
View
76
Download
0
Embed Size (px)
DESCRIPTION
主題 : Big number ( 大數 ). 解題技巧 什麼是大數? 大數運算 加法 減法 乘法 例題講解 : H.91.4 歷年題目. 什麼是大數?. 怎麼存下面的數字 100000 : int (-2 31 ~ 2 31 -1) 10000000000 : __int64 (-2 63 ~ 2 63 -1) 1000000000000000000000 : 怎麼存? 目前 C 只能用 64 bit 儲存整數, 64 bit 存不下的數字就稱為大數. 如何儲存大數. 正確評估 max_len - PowerPoint PPT Presentation
Citation preview
1
主題 : Big number ( 大數 )
解題技巧 什麼是大數? 大數運算
加法 減法 乘法
例題講解 : H.91.4 歷年題目
2
什麼是大數? 怎麼存下面的數字
100000 : int (-231 ~ 231-1) 10000000000 : __int64 (-263 ~ 263-1) 1000000000000000000000 : 怎麼存?
目前 C 只能用 64 bit 儲存整數, 64 bit 存不下的數字就稱為大數
3
如何儲存大數 正確評估 max_len
最大數要多少位元 (10 進位 ) ,保證不會 overflow 5 位數 + 4 位數 <= 6 位數 5 位數 × 4 位數 <= 9 位數
用 string 來儲存 char x[max_len+1] x = “684597315274” 將每個位數用一個字元來儲存,運算時再轉換回數字
4
如何儲存大數 用整數陣列來儲存 (for 運算,較容易 )
int num[max_len] = { 4, 7, 2, 5, 1, 3, 7, 9, 5, 4, 8, 6, 0, ..., 0}
要記得補 0
不補 0 要記有效位元長度,速度快但程式不好寫
個位數
320000000 4
500000000 6×
5
大數運算 大數運算
加法 乘法 減法
6
大數加法 原理
既然 C 程式內建的加法不能用,那就用最原始的加法
要注意進位的動作
4 1 7 8
4 2 5+
3
1
0
1
64
7
資料結構 int num1[max_len], num2[max_len]
用來儲存數字
int answer[max_len] 用來儲存結果
int carry
8
大數加法 123456789 + 987654321 ?
把 123456789 存在 num1 之中, 987654321 存在 num2 ,結果存在 answer 中
num1
num2
1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1+
111111111
111111111 0answer
0carry
0
0
9
C code
void big_add( int *num1, int *num2, int *answer ){int i;
carry = 0; for ( i = 0 ; i < max_len ; i++) {
answer[ i] = (num1[ i] + num2[ i] + carry) % 10;carry = (num1[ i] + num2[ i] + carry) / 10;
}if (carry != 0)
printf(“Overflow!!!\n”);}
10
10
大數乘法 原理
乘法其實就是很多個加法 注意進位和位數
4 1 7 8
4 2 5×
09804302
2
65381
21763301
1
0565771011010
11
資料結構 num1, num2, carry 和加法一樣
中間的過程要用二維陣列來儲存? 不用,和加法一樣只需要一個一維陣列 answer 每次有新的值乘出來之後,就把它加到適當的位置去
12
10
4 1 7 8
4 2 5×
09804302
2
65381
21763301
1
0565771011010
4 1 7 8
4 2 5×
09802
6538
0565771
054401
21761
++
+
0
00
0
0000
000
0000
000
00
00
0
13
C code
void big_mul( int *num1, int *num2, int *answer ){int i, j; for (i = 0; i < max_len) ; i++){
carry = 0; for (j = 0; j < max_len ; j++){ if (( i + j ) < max_len) answer[i+j] = (answer[i+j] + num1[j] * num2[i] + carry) % 10;
carry= (answer[i+j] + num1[j] * num2[i] + carry) / 10; }}
}
14
小技巧 在做大數運算時,可以將數個位數當成同一個位數來運算 之前的例子都是十進位,若換成百進位的話結果會如何?
4 1 7 8
4 2 5×
5 019
4 41 010
1 23
6 711
0565771
15
當每一次運算所使用的位數增加時,總共所需要計算的次數就會減少,所要開的陣列大小也跟著變少
若陣列的型態為整數的話,則最多只能以萬進位為計算的單位 10000*10000 < 2^32
16
大數減法 原理
跟加法、乘法差不多 要注意借位 可以先判斷減數或被減數大,拿大的去減小的,最後再補正負號即可
17
大數減法 425 – 4178 = – (4178 – 425 ) = –3753
4 1 7 8
4 2 5–
35
-1
73–
18
C code/* 假設 num1 比 num2 大 */void big_sub( int * num1, int *num2, int *answer ){int i;
carry = 0;for (i = 0; i < max_len ; i++) {answer[ i] = num1[ i] – num2[ i] + carry;if (answer[ i] < 0) {answer[ i] = answer[ i] + 10; // 若是百進位則加 100 carry = -1;}else carry = 0;}if (carry != 0)printf(“Underflow!!!\n”);
}
19
例題講解 : H.91.4 http://www.cs.tku.edu.tw/info_race2002/codeq.htm
[a0, a1, …, an] ,其中每一個 ai 都是 0 到 9 之間的整數,而且 n 50 ( 最多有 51 個數字 )
na
aa
a
1
11
11
2
1
0
…
20
Example
8
5
5
31
1
3
21
11
1
2
11
11
11
1
將連分數轉成分數
21
Sample input/output
Sample input:
1,1,1,2
Sample
5
8
a0,a1,a2,a3
分子
分母
22
分析
21
0 11
1
aa
a
2
210 1
11
aaa
a
1
1
21
20
aaa
a
1)1(
1
21
2210
aa
aaaa 2210
21)1(1aaaa
aa
= =
= =
23
分析 所需的動作
乘法 加法 分子分母對調
Easy ?
24
分析 每個 ai 最大有可能到 9 ,最多可能有
51 個 9 連乘 9^51 >> 2^63
需要大數加法和大數乘法
25
需要的資料結構 int num[51]
儲存 a0 到 an,最多有 51 個數
int x[51] // 分子 9^51 位數最多只會有 51 位
int y[51] // 分母
26
Program structure
intial_ 分子 _ 分母 ();
for (i = n – 1; i >= 0; i++){
count_new 分子 _new 分母 ();
}
27
C code
int x[51], y[51], newx[51], newy[51];x[0] = 1;
y[0] = an;for (i = n – 1; i >= 0; i++){
newx y;
newy big_add ( big_mul ( y , ai) , x ) ;
/* newy = y × ai + x; */x newx;y newy;
}
這裡的大數乘法是一個大數乘以一個整數,較簡單
28
歷年題目 練習題
A. 495 Fibonacci Freeze http://acm.uva.es/p/v4/495.html
A. 623 500! http://acm.uva.es/p/v6/623.html
A. 338 Long Multiplication http://acm.uva.es/p/v3/338.html
A. 619 Numerically Speaking http://acm.uva.es/p/v6/619.html
挑戰題 2004 兩岸清華學生程式比賽 Problem D
http://venus.cs.nthu.edu.tw/~jous/NTHU2004-Problems.doc http://venus.cs.nthu.edu.tw/~jous/pd.exe
A. 288 Arithmetic Operation with Large Integers http://acm.uva.es/p/v2/288.html
其它歷年題目 無