AOJ0005
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0005
题意
给定两个数,求其最大公约数GCD以及最小公倍数LCM。
思路
求最大公约数一般用辗转相除法,然后就得到了最小公倍数。
更详细的分析参见我的博客文章:
数论——最大公约数和最小公倍数算法
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
unsigned GCD(unsigned a, unsigned b)
{
if (!b) return a;
return GCD(b, a%b);
}
unsigned LCM(unsigned a, unsigned b)
{
return a / GCD(b, a-b) * b;
}
int main(void)
{
unsigned a, b;
while (scanf("%u %u", &a, &b) != EOF) {
if (a < b) swap(a, b);
printf("%u %u
", GCD(a, b), LCM(a, b));
}
return 0;
}
POJ2429
POJ1930
http://poj.org/problem?id=1930
题意
将一个无限循环小数转化成分母最小的精确分数值。
注意:循环的部分不一定是最后一位,有可能从小数点后面全是循环部分。
思路
将分数分成循环的部分和非循环的部分:
设分数为0.i1 i2 i3 i4 .. ik j1 j2 j3 .. jc,其中i1 ~ ik 为非循环的部分,j1 ~ jc为循环部分。
非循环的部分可以拆成 b / a 其中 b = ( i1…ik) a = 10 ^ (k);
循环的部分可以拆成 bb / aa 其中 bb = (j1 .. jc) aa = 10 ^ (k + c) - 10 ^ ( k);
则所求分数为 b / a + bb / aa,通分得 (b * aa + bb * a) / a * aa,约分得答案(用最大公约数求)。
另外,据说数据会有全是0的坑爹数据,但我没有被坑到。
代码
Source Code
Problem: 1930 User: liangrx06
Memory: 172K Time: 16MS
Language: C++ Result: Accepted
Source Code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <algorithm>
using namespace std;
int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a%b);
}
int exp10(int x)
{
int res = 1;
while (x--)
res *= 10;
return res;
}
int main(void)
{
int i, j, a, b, a10, b10, g, len;
int m, n;
string s, sa, sb;
while(cin >> s)
{
if(s == "0")
break;
len = s.size();
for(i = 1; i <= len-5; i++) {
sa = s.substr(len-3-i, i);
a = atoi(sa.c_str());
a10 = exp10(i);
j = len-5-i;
sb = s.substr(2, j);
b = atoi(sb.c_str());
b10 = exp10(j);
int tn = (a10-1)*b10;
int tm = b*(a10-1) + a;
g = gcd(tn, tm);
tn /= g;
tm /= g;
if (i == 1 || i > 1 && tn < n) {
n = tn;
m = tm;
}
}
printf("%d/%d
", m, n);
}
return 0;
}