http://domen111.github.io/UVa-Easy-Viewer/?10370
有 個班級,每個班級有 個學生
給定 個學生的成績,輸出每個班級有多少百分比的學生成績比班平均還高
每個班級的成績都可以算出一個平均,算出成績後一個一個比對誰的成績比平均高,每遇到一個就紀錄下來
有了紀錄的數量以及班級學生的總數,就可以算出答案囉!
不過要特別注意兩個地方
double
來儲存fixed
和 setprecision
有 個班級,每個班級有 筆成績要輸入,輸入的時間複雜度為
每次算出平均後,需要一個一個比對有多少大於平均的成績,時間複雜度為
總時間複雜度為 , 約為
http://domen111.github.io/UVa-Easy-Viewer/?10491
現在有一場遊戲,遊戲的規則是這樣的:
舞台上有許多扇門,每個門後都有一輛車或是一隻牛
身為參賽者的你,目的就是要選到有車的那扇門。在遊戲的一開始,你會選擇一扇門
接下來主持人會開啟幾扇在你選擇的門以外,藏有牛的門,題目保證這扇門是存在的
問題如下:
在有 隻牛, 輛車,主持人開啟 扇門的情況下,你贏得車的機率是多少,輸出到小數點後第 5 位
這題其實是數學題喔!在高中的機率當中也有類似的題目,想法是這樣的
一開始參賽者選擇的情況有兩個
選擇了藏有牛的門
一開始選擇藏有牛的門的機率為
此時,剩下的門的數量為 ,車的數量為
在這個前提下,選到車的機率為
選擇了藏有車的門
一開始選擇藏有車的門的機率為
此時,剩下的門的數量為 ,車的數量為
在這個前提下,選到車的機率為
最後將這兩種情況的機率相加,就會是我們的答案
記得,這裡的機率可能會含有小數,要使用 double
儲存
並且輸出要到小數點後第 5 位,要使用 fixed
和 setprecision
每一筆輸入在計算上時間複雜度為
總時間複雜度為
https://toj.tfcis.org/oj/pro/99/
給一個二階矩陣
求 是否非零,誤差值在小數點後 7 位
這題是要測試是否知道使用 eps
在 C/C++ 當中,小數點只能是"大致上"準確的,所以像是小數再判斷是否為零不能直接判斷
我們通常會設定一個誤差值,像是本題就是 ,當我們的值小於該誤差值就會被判定為 0
所以我們只需要改用 eps 來判斷就可以囉
計算以及判斷都只有一次,時間複雜度為
http://domen111.github.io/UVa-Easy-Viewer/?12195
小李在學作曲,他想要做出每一小節長度都是 1 拍的曲子
可以用的音符有這些:
我們會拿到一串以 /
切割的字串,每個 /
之間代表一個小節的內容
請你判斷出其中有多少小節的長度剛好是 1 拍
每個小節我們都拿一個變數紀錄音符的總長度
我們可以跟著題目的想法做,遇到相對應的音符代號,就將長度記錄下來
在每個小節結束後,如果長度剛好為 1 拍,就記錄下來
輸入的部分我們可以這樣處理:
每次遇到 /
就看看我們紀錄音符長度的值是不是剛好為 1 拍,如果是就紀錄下來
無論有沒有剛好為 1 拍,都必須要將記錄長度的變數歸零
如果不想要處理麻煩的小數問題,可以這樣想
觀察可以用的音符,可以發現到所有音符長度的最小公倍數是 64
將全部的音符長度都乘上 64 後,都會變成整數,這樣就完美的忽略小數的問題了!
那麼一個小節的長度也就變成 64 囉!
每次輸入會針對字串的每個字原作相對應的計算
而每個計算的時間複雜度為
每筆測資的時間複雜度為
http://domen111.github.io/UVa-Easy-Viewer/?113
給定兩個整數 , ,求 的 次方根 ,且保證 為整數
的 次方根等同於 的 次方
直接使用內建的 pow
即可
有一點需要特別小心,因為 C++ 預設在輸出小數時如果太小,可能會變成以科學記號表示
要排除這種狀況,我們可以用之前學過的 setprecision
來解決
setprecision(n)
等同四捨五入取到小數點後第 位,這裡我們要取整數,所以放 0
每筆測資時間複雜度可以視為
不過詳細可以參考這篇: https://stackoverflow.com/questions/4638473/how-to-powreal-real-in-x86
http://domen111.github.io/UVa-Easy-Viewer/?1185
有 筆測資,每筆測資包含一個數字 ,求 是幾位數
如果只給一個數字 ,要求 是幾位數我們可以用高中學到的 的整數得到答案
根據 的性質, =
在階乘計算上數字成長速度很快就會超過我們能儲存的大小,所以我們要利用前面提到的 性質
要計算 的位數,等同於
其中, 表示取整數
每筆測資都需要花 的時間計算
總時間複雜度
我們可以將所有答案都先算起來,這樣每次詢問就可以直接回答
預先處理答案的時間複雜度為
每筆詢問的時間複雜度為
總時間複雜度為
http://domen111.github.io/UVa-Easy-Viewer/?10061
給兩個數 , ,求
問幾位數的問題比較簡單,如同前一題,只是進位制不同
要計算 在 進位制下是幾位數,等同於計算 取整數
由於內建的函式庫並沒有直接計算 底數為任意數的方式,這裡要使用換底公式
根據 的性質,可以得到
兩個性質合起來
先從 10 進位開始想,尾數要是 0 則它必定會是 10 的整數倍
例如: 10, 100, 1000, 1020 …
這個數一定要有 10 的因數 ,也就是他必須要至少同時有一個 2 和 5 的質因數
換到其他進位制仍然相同
所以說,我們只需要紀錄 的質因數各有多少個
如果說 的質因數有
那麼 至少要包含整數倍的 ,才能是 的整數倍
所以接下來針對 的每個質因數 ,計算 在 中的個數與在 中的個數之比值,其中最小值就會是答案
例如:
整理一下 的質因數個數
tbl 2 3 4 5 6 7 個數 4 2 0 1 0 1 整理一下 的質因數個數
mPrime 2 3 4 5 6 7 個數 4 0 0 0 0 0 所以說,必須至少含有 4 個 2 ,尾數才能有一個 0
這裡可以發現答案是
至於質因數個數的部分,我們可以先預先建立一個表格,紀錄每個數字內的最小質數
例如: 10 -> 2 ; 7 -> 7 ; 9 -> 3
接下來,我們每次除以最小質因數,經過的就會是他的質因數了
例如: 36 –(/2)–> 18 –(/2)–> 9 –(/3)–> 3 –(/3)–> 1
求得
他就會像是這樣,將每個是自己倍數的數值紀錄成自己
例如: 偶數都會被記錄成 2 , 質數都會記錄成自己
預處理質數時間複雜度約為
每次初始化的時間複雜度約為
計算尾數的時間複雜度約為
計算位數的時間複雜度約為
總時間複雜度約為
大約為
這題數字小,就來提供比較單純的解法。
找質因數的部份因為數字不大,其實可以亂做;
從 開始把每個整除的數字全部除到不整除,就可以了。
這可以保證找到任何整除的數字 時,所有比它小的數字都已不整除,
那麼 一定是質數,否則必存在比它小的數字整除,矛盾。
由於是 到 的連乘,假設今天要找質因數 出現幾次,
由於每 個數字就有一個擁有 所以除以 即可;
這 個 的倍數數字中,每 個就有一個擁有 ,
或者說每 個整數就有一個擁 也可以,一樣意思,
這樣可以很快找到 對任意質因數 總共出現幾次。
每組需要質因數最糟
質因數最多 個,每個最糟要 的計算量
計算位數時
統合一下大約每組測資是
http://domen111.github.io/UVa-Easy-Viewer/?10219
求 的數值是幾位數
我們要求的是 取整數後的值
已知
則
又因為 ,也就是說可以保證兩個 Sigma 跑的次數是相同的
所以在實作上只需要一個迴圈即可
另外,計算 時,當我們的 時,可以轉換成 ,讓數值變得更小一點
每次計算時間約為 ,而需要計算 次,每筆測資時間複雜度為
http://domen111.github.io/UVa-Easy-Viewer/?10387
有一張長寬分別為 的桌子,在他的正中央有一顆球,這顆球會以某個速度 ,以角度 在桌子碰撞,分別在桌子的直向與橫向處撞擊 次後回到初始位置
求這顆球的初速 以及初始角度
並且假定球再碰撞過程中並無能量損耗,一切都是完美狀況
可以先畫一張圖看看,會發現到球在碰撞的過程當中與橫向之間的角度,也就是初始角度 都不會改變
並且由於無論如何球都必須要回到原點,每次碰撞過後為了回到原點,必須移動朝向方向(橫向或直向)移動一個長或寬的距離
所以我們可以透過 和 求到球在桌面上的橫向與直向的移動總距離
透過畢氏定理可以求得球的移動距離,再除以時間就會是速度
角度的部分可以透過 求得
由於 C++ 經過 求到的是弧度,而題目要的是角度,所以要再另外計算一個弧度是多少角度
每次輸入的計算時間可估為
SCIST 演算法 題解