1. 程式人生 > >刷題總結——(一道很妙的題)Resistance(ssoj 歐幾裏得 )

刷題總結——(一道很妙的題)Resistance(ssoj 歐幾裏得 )

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 歐幾裏得 )