POJ 1930: Dead Fraction
概要
小数が与えられる.循環小数と見たとき,分母が最も小さくなる分数表示を求める.
解法
循環する区間を仮定して分数に直すという操作を繰り返す.
n桁の循環する小数は,cを循環する部分を表す整数とすると,c/(10^n-1)で得られる.
typedef unsigned long long ull; ull gcd(ull x, ull y){ return y ? gcd(y, x%y): x; } string s; int main(){ for(;;){ cin >> s; if(s == "0") return 0; s = s.substr(2, s.size()-5); ull p, q, v, w, g; p = q = ULLONG_MAX; v = 1; w = 1; for(int i = 0; i < s.size(); ++i) w *= 10; for(int i = 0; i < s.size(); ++i){ ull a, b, c, d; if(i == 0) a = 0; else sscanf(s.substr(0, i).c_str(), "%llu", &a); b = v; sscanf(s.substr(i).c_str(), "%llu", &c); d = w - 1; g = gcd(a, b); a /= g; b /= g; g = gcd(c, d); c /= g; d /= g; g = gcd(c, v); c /= g; d *= v / g; g = gcd(b, d); a = a * (d / g) + c * (b / g); b = b / g * d; g = gcd(a, b); a /= g; b /= g; // cerr << ">" << a << "/" << b << endl; if(b < q){ p = a; q = b; } v *= 10; w /= 10; } cout << p << "/" << q << endl; } }