csu 1303 Decimal (数论题)

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1303

1303: Decimal

Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 589  Solved: 61 [Submit][Status][Web Board]

Description

任意一个分数都是有理数,对于任意一个有限小数,我们都可以表示成一个无限循环小数的形式(在其末尾添加0),对于任意一个无限循环小数都可以转化成一个分数。现在你的任务就是将任意一个无限循环小数转化成既约分数形式。所谓既约分数表示,分子和分母的最大公约数是1。

Input

有多组数据。

每组数据一行。输入为0.a1a2a3...ak(b1b2...bm)的形式,其中a1a2a3...ak为非循环部分,(b1b2b3..bm)为循环部分。数据保证非循环部分的长度k和循环部分的长度m不会超过8.

Output

对于每组测试数据输出A/B,其中A是分子,B是分母,A,B均为整数。

Sample Input

0.0(714285)
0.0(5)
0.9(671)

Sample Output

1/14
1/18
4831/4995


【题解】:

  分成两部分求解:
  第一部分非循环部分,这部分很好求:(非循环部分)/ (非循环位数*10) 例如:0.3 == 3/10
  第二部分为循环部分,(循环部分)/ (循环位数*10-1) 例如: 0.(3) == 3/(10-1) == 1/3
  
  当然像 0.1(3)这种既有非循环又有循环的,就通过两部分想加就行
要注意的是:循环部分为 (循环部分)/ ((循环位数*10-1)* (非循环位数*10))

【code】:
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 
 8 char str[100];
 9 
10 long long gcd(long long u,long long v)
11 {
12     long long temp=u;
13     if(u>v) temp=u,u=v,v=temp;
14     while(temp)
15     {
16         temp = v%u;
17         v=u;
18         u=temp;
19     }
20     return v;
21 }
22 
23 int main()
24 {
25     long long arr[]={1,10,1e2,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12};
26     while(~scanf("%s",str))
27     {
28         int i,f_cnt=0,x_cnt=0,flag = 0;
29         long long s1=0,s2=0;
30         int len = strlen(str);
31         for(i=0;i<len;i++)
32         {
33             char ch = str[i];
34             if(ch=='(')  //取括号里面的循环部分
35             {
36                 i++;
37                 while(i<len&&isdigit(str[i]))
38                 {
39                    s2=10*s2+str[i]-'0';
40                    x_cnt++; //循环位数计算
41                    if(i+1>=len||!isdigit(str[i+1])) break;
42                    i++;
43                 }
44                 flag=0;
45             }
46             if(flag)  //小数点后面的非循环部分
47             {
48                 while(i<len&&isdigit(str[i]))
49                 {
50                     s1=10*s1+str[i]-'0';
51                     f_cnt++; //非循环位数计算
52                     if(i+1>=len||!isdigit(str[i+1])) break;
53                     i++;
54                 }
55             }
56             if(ch=='.')
57             {
58                 flag = 1;  //标记小数点的出现
59             }
60         }
61         //非循环部分 s1 / arr[f_cnt]
62         //循环部分 s2 / (arr[x_cnt-1]-1) * (1 / arr[f_cnt])
63         if(x_cnt==0)    arr[x_cnt]=10;  //排除当x_cnt为0时 arr[cnt]-1出现除数为0的情况
64         long long up = s1*(arr[x_cnt]-1)+s2;
65         long long down = (arr[x_cnt]-1)*arr[f_cnt];
66         long long temp = gcd(up,down);
67         if(x_cnt==0)    arr[x_cnt]=1; //记得改过来
68         printf("%lld/%lld
",up/temp,down/temp);
69     }
70     return 0;
71 }
原文地址:https://www.cnblogs.com/crazyapple/p/3293498.html