poj 1930 Dead Fraction

缘起

日常浪费生命 poj 1930 Dead Fraction

分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
给你一些小数,要你推导出原来的分母最小的既约分数.

【输入】
多样例. 每行一个小数. 形如 0.ddddd..., d们来自0~9, 不是所有的都是0. 最后一个0的,表示输入结束

【输出】
输出原先的既约分数

【样例输入】
0.2...
0.20...
0.474612399...
0

【样例输出】
2/9
1/5
1186531/2500000

【限制】
1s

【提示】
Note that an exact decimal fraction has two repeating expansions (e.g. 1/5 =
0.2000... = 0.19999...).
1186531/2500000=0.47461239999999999999999999999999999999999999999999999...

如果给你a,b 要你打印a/b的无限循环小数,就是一个辗转相除法而已. 但是本题是要逆过来——已知小数求原先的a和b.

其实就是

A=0.abcdefgh…, 假设 efgh是循环节, 则

10^8*A = abcdefgh.edgh

10^4*A = abcd.efgh

则(10^8-10^4)*A = abcdefgh-abcd

所以可得A(gcd算法得出)

还需要枚举循环节长度(上面的例子是循环节长度为4).

唉,此题也没给范围. 差评

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//#include "stdafx.h"

#include <stdio.h>
#include <string.h>
//#define LOCAL
typedef unsigned long long ULL;

char d[105];

ULL gcd(ULL a, ULL b)
{
return b?gcd(b,a%b):a;
}

int main()
{
#ifdef LOCAL
freopen("d:\\data.in", "r", stdin);
//freopen("d:\\my.out", "w", stdout);
#endif
while(gets(d))
{
int len = 0;
bool flag = true;
while(d[len])
{
if (d[len]=='.') // 遇到.
{
if (flag) // 第一次遇到.
{
flag = false;
}
else // 第二次遇到.
{
break;
}
}
len++;
}
if (len==1)
{
break;
}
ULL ans_a,ans_b,ans_aaa, ans_bbb = (1LL<<63); // ans_a/ans_b
len-=2;
ULL s = 1,t,x = 0,y=0;
for (int i = 1; i<=len; i++)
{
s*=10;
x = x*10+(d[i+1]-'0'); // 洪特规则
}
t = s,y=x;
for (int i = 1;i<=len; i++) // 枚举循环节长度
{
t = t/10;
ans_b = s-t;
y = (y-(d[len-i+2]-'0'))/10;
ans_a = x-y;
ULL gg = gcd(ans_a, ans_b);
ans_a/=gg;
ans_b/=gg;
if (ans_bbb>ans_b)
{
ans_aaa = ans_a;
ans_bbb = ans_b;
}
}
printf("%llu/%llu\n", ans_aaa, ans_bbb);
}
return 0;
}

ac情况

20822332 yfsyfs 1930 Accepted 112K 0MS C++ 1053B 2019-08-31 21:04:00