CF200は本番参加。A,Cは無事解けたものの、Bはpretest通過後WAして微妙な順位に終わった。
http://codeforces.com/contest/343/problem/A
問題
電気回路において、抵抗を直列に抵抗値はその合計に、並列につなげると抵抗値は調和平均になる。
ある回路の抵抗値が有理数A/Bの形で与えられる。
抵抗値1の抵抗を複数個使って全体の抵抗値をA/Bにするとき、必要な抵抗の数を最少化せよ。
解法
再帰的に行う。
B=1ならA個直列、A=1ならB個並列に抵抗値1の抵抗を並べればよい。
それ以外の場合、A>BならA/B個分の抵抗値1の抵抗と、抵抗値(A%B)/Bを実現する抵抗を直列につなげばよいので、抵抗値(A%B)/Bを実現する抵抗の数を再帰的に求めてA/Bと足せばよい。
A
ll gcd(ll a, ll b) { return (b==0)?a:gcd(b,a%b);} ll dodo(ll A,ll B) { ll g=gcd(A,B); A /= g; B /= g; if(B==1) return A; if(A>B) return A/B + dodo(A%B,B); if(A==1) return B; return B/A+dodo(A,B%A); } void solve() { int f,r,i,j,k,l, x,y; ll A,B; cin>>A>>B; cout << dodo(A,B) << endl; }
まとめ
最大公約数って今までまじめに書いてたけど、g++は(STLは?)__gcdって関数があるのね。