# 桃園高中第一次資訊讀書會 資訊讀書會?講一下可能跟競程有關(或無關)的東東。 ~~(如果有寫錯噴小力一點,但我猜應該沒人看)~~ **** # 時間複雜度 1. Big-O( Ο ):演算法時間函式的上限(Upper bound) 1. Omega( Ω ):演算法時間函式的下限(Lower bound) 1. Theta( θ ):演算法時間函式的上限與下限 先簡單介紹Big-O,他的嚴格定義是,找到一個n0與c使得 f(n)<=O(c*n)在(n>=n0)的情況下,舉例:f(n)=3n^2他就屬於 學者發表在期刊上的演算法,通常是找到更加優化的解,例如O(n^2)變成 O(nlogn),或是找到新的資料結構能優化演算法,例如binary indexed tree。 # p與np 先介紹指數時間跟多項式時間 1. 指數時間:問題求解所花的步驟,會隨著n的輸入規模成指數成長。例如:T(n)= 2^n(n每多1,步驟就要多兩倍) 3. 多項式時間:能夠表示成多項式,例如:T(n)=n^3+ 2n^2+n-7 指數時間遠遠多於多項式時間 你一定能夠找到一個n,使得指數時間遠遠大於多項式時間,這是必然的。  2^n 屬於非多項式時間。 n^k 是多項式時間。 # 大數問題 ***假設問題*** 真實世界的問題都挺複雜的,我們先從簡單的情況考慮問題。 1. 如果我們只是想要在一台計算機加減乘除,多餘的位數要怎麼處理?(假設計算機最大顯示位數是9-10位) 2. 如果除法要求求出他的循環小數要怎麼做?  大數加法 15000000+15000000=30000000,這很簡單,~~小學生都會寫程式算~~。 但如果是10^30+ 10^30 超出 int or long long 範圍的怎麼辦? ~~int128~~ ```cpp= _int128 read() { __int128 x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (c >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } void print(__int128 x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) print(x / 10); putchar(x % 10 + '0'); } bool cmp(__int128 x, __int128 y) { return x > y; } ``` 程式碼來源:https://codeforces.com/blog/entry/75044#:~:text=As%20an%20extension%20the%20integer,an%20unsigned%20128%2Dbit%20integer. ~~建議不要亂用~~~~畢竟他最大也只能存(2^127)-1 ~ (-2^127) **正題:** 怎麼寫大數加法? int 只能存(10^9) ,long long 只能存(10^18),我們觀察一下這個數字 184639257 觀察後發現可以拆成 9 個 int,什麼東西可以存很多個數字或字元? :::spoiler [hint] 陣列 ::: ******* 還有一個問題要解決,直接把大數當int or long long 輸入會溢位,要怎麼處理? :::spoiler [hint2] 字元或字串 ::: ```cpp= //輸入兩個大數自動相加,格式: 100 200 輸出:300 #include<bits/stdc++.h> using namespace std; int a[10005],b[10005],c[10005]; int main(){ string n,m; cin>>n>>m; reverse(n.begin(),n.end());//翻轉相反頭尾 reverse(m.begin(),m.end()); for(int i=0;i<=n.size()-1;i++){ a[10000-i]=n[i]-'0'; } for(int i=0;i<=m.size()-1;i++){ b[10000-i]=m[i]-'0'; } //for(int i=9980;i<=10000;i++) cout<<a[i]; //for(int i=9980;i<=10000;i++) cout<<b[i]; for(int i=10000;i>0;i--){ c[i]=c[i]+a[i]+b[i]; if(c[i]>=10) c[i-1]++; c[i]%=10; } int ans = 0; for(int i=1;i<=10000;i++){ if(c[i]!=0) { ans=i; break; } } if(!ans) cout<<0<<'\n'; for(int i=ans;i<=10000;i++){ cout<<c[i]; } }//超級偷懶,空間開太大了 ``` 時間複雜度為O(n) 還有一個問題,我們能繼續優化他嗎??? 幾個方向 1. 如果我們知道我們要算幾位數+幾位數? 2. 我們可以分塊分成17|17|17 開三個long long ? 時間複雜度是? **** **大數減法** easy,但細節要討論,怎麼借位? 10-5是很簡單的借位,但100-5? 1000-5? 10000-5? 還有什麼細節需要討論的?如果第一個數小於第二個數呢? ```cpp= 之後補 ``` **** 大數乘法 怎麼乘?如果有小數點怎麼辦呢? 或是兩個都小於1,但大於0怎麼辦呢? 時間複雜度? **** 大數除法 **** ~~先把我婆放上去~~~~~~ 
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up