【HDU】1717 小数化分数2 ——计数原理

小数化分数2

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2988    Accepted Submission(s): 1224

 

Problem Description
Ray 在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢?
请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。
 
Input
第一行是一个整数N,表示有多少组数据。
每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。
 
Output
对每一个对应的小数化成最简分数后输出,占一行。
 
Sample Input
3
0.(4)
0.5
0.32(692307)
 
Sample Output
4/9
1/2
17/52
 
Source
 
Recommend
lcy   |   We have carefully selected several similar problems for you:   1715  1716  1166  1719  1722 
 
题解:首先要知道无限循环小数分数形式的构造方法:分子为最小循环节,分母为对应位数的99..9 如已知无限循环小数:0.568568……以568为循环节,那么这个小数的分数形式就是568/999,题中,我们将小数的有限部分和无限循环部分分开处理,得到两个分数,再相加化简,所得即为所求。
 
代码如下:
 1 #include <cstdio>

 2 #include <cstring>

 3 

 4 typedef long long ll;

 5 

 6 const int LEN = 11;

 7 

 8 char num[LEN];

 9 ll a, b, c, d, e, f; //形如a/b, c/d, e/f的分数

10 

11 ll diypow(int n) //求10的n次方

12 {

13     ll ans = 1;

14     for(int i = 0; i < n; i++)

15         ans *= 10;

16     return ans;

17 }

18 

19 ll gcd(ll x, ll y) //最大公约数

20 {

21     while(x != y){

22         if (x > y)

23             x -= y;

24         else

25             y -= x;

26     }

27     return x;

28 }

29 

30 void cacnum() //处理输入的数,将其有限小数部分以及无限循环部分分别用分数表示

31 {

32     a = b = c = d = 0;

33     int len1 = 0, len2 = 0; //len1 len2分别是有限小数部分分子的长度和无限小数循环节的长度

34     int len = strlen(num);

35     for(int i = 0; i < len; i++){

36         if (num[i] == '('){

37             len2 = len - i - 2;

38             len1 = i - 2;

39             break;

40         }

41         if (i == len-1){

42             len1 = i - 1;

43         }

44     }

45     if (num[2] == '(')

46         sscanf(num, "0.(%I64d)", &c);

47     else

48         sscanf(num, "0.%I64d(%I64d)", &a, &c);  //正则表达式读入

49     if (len1 != 0)

50         b = diypow(len1); 

51     if (len2 != 0){

52         d = diypow(len2) - 1;

53         d *= diypow(len1);  //构造分母

54     }

55 }

56 

57 int main()

58 {

59     //freopen("in.txt", "r", stdin);

60     int T;

61     scanf("%d", &T);

62     while(T--){

63         scanf("%s", num);

64         cacnum();

65         if (a != 0 && c != 0){ //如果既有有限部分又有无限部分,两个分数相加

66             e = a * d / b + c;

67             f = d;

68         }

69         else if (a == 0){

70             e = c;

71             f = d;

72         }

73         else if (c == 0){

74             e = a;

75             f = b;

76         }

77         ll g = gcd(e, f); //取分子分母的最大公约数用来化简

78         printf("%I64d/%I64d\n", e / g, f / g);

79     }

80     return 0;

81 }

 

你可能感兴趣的:(HDU)