刷題總結——(一道很妙的題)Resistance(ssoj 歐幾裏得 )
阿新 • • 發佈:2017-10-07
wrap log case 空間復雜度 sso bsp 題解 方法 復雜度
題解:
題目背景
151006 T1
題目描述
Picks 喜歡電路。這天他在研究元電路的時候,需要一個阻值為 (p/q)? 的電阻,然而他家中只有一大堆電阻為 1? 電阻。由於技術問題,Picks 每次只能把一個電阻串聯或並聯進整個電路。而 Picks 拿著這麽大一堆電阻覺得很浪費,於是他找到你,希望你能告訴他最少用多少個電阻才能拼出他所需要的電阻。
輸入格式
輸入一行,為兩個正整數 P 和 Q 。
輸出格式
輸出一行一個整數,即最少要用的電阻個數。
樣例數據 1
輸入 [復制]
3 2
輸出
3
備註
【樣例說明】
要得到一個 (3/2)? 的電阻,可以用兩個電阻並聯,再串聯一個電阻。
【數據範圍】
30% 的數據:1≤P,Q≤10;
100% 的數據:1≤P,Q≤1018。
題解:
引用ssoj官網題解:
考慮現在我們的電阻為 a/b ?,串聯一個電阻上去,電阻變為(a+b)/b ?.
並聯一個電阻上去,電阻變為 a/(a+b) ? 。
假設我們需要的電阻為 P/Q ?,每次我們都能將 P 減小到比 Q 小,也能將 Q 減小到比 P 小。
那麽,我們能進行的操作為:P/Q ? → (P mod Q)/Q ? 或 P/Q ? → P/(Q mod P) ?
這樣的最優性是顯然的。
考慮這個操作,會發現和 Euclid(歐幾裏得) 算法的步驟很接近。由於 Euclid 算法的復雜度為O(logN),故此方法也是。
時間復雜度:O(logN),空間復雜度:O(1)。
其實這道題和歐幾裏得的思想並沒有太大關系···只是形式上一樣···以後遇到數論題要多推一下式子···
代碼:
#include <stdio.h> #ifdef WIN32 #define OTL "%I64d" #else #define OTL "%lld" #endif #define ll long long ll p, q, ans; void Deal( ll p, ll q ) { if ( q == 0 ) return; ans += p / q; Deal( q, p % q ); }int main() { //freopen( "resistance.in", "r", stdin ); //freopen( "resistance.out", "w", stdout ); scanf( OTL OTL, &p, &q ); Deal( p, q ); printf( OTL, ans ); return 0; }
刷題總結——(一道很妙的題)Resistance(ssoj 歐幾裏得 )