CUG 数学进阶

题目链接:http://acm.cug.edu.cn/JudgeOnline/contest.php?cid=1047

.

.

.

I 题目链接:http://acm.cug.edu.cn/JudgeOnline/problem.php?cid=1047&pid=8

题意:给你一个0.xxx...表示的无限循环小数,求其表示成分数形式时分母最小的那个分式。

思路:首先我们要知道如何将一个无限循环小数(已知循环结)化为分数,剩下的过程就是枚举所有循环结来寻找满足题目要求的答案。

下面来推导下如何将一个无限循环小数化为分数:

X = 0.a1a2…an(b1b2…bm)                 (1)

X *10^n = a1a2…an. (b1b2…bm)             (2)

X *10^n - a1a2…an = 0. (b1b2…bm)            (3)                               

(X *10^n - a1a2…an)*10^m = b1b2…bm. (b1b2…bm)     (4)

(X *10n - a1a2…an)*10^m - b1b2…bm = 0. (b1b2…bm)  (5)

(3)和(5)相等,联立解得:

    X = (a1a2...anb1b2...bm - a1a2...an)/(10^(n+m) - 10^n)   (*)

求出了(*)题目就基本做出来了。

**  使用%[]格式可以输入一个字符集,scanf(" 0.%[0-9]...")格式可以输入前面是0.开头后面是...结尾,中间是由0-9内范围的数字字符组成。

关于更多的字符串输入格式可以参见以前的博文C/C++中字符串的输入问题

** atio函数的介绍

头文件:#include <stdlib.h>

函数原型:int atoi( const char *str );

函数功能:将字符串str转换成一个整数并返回结果。参数str 以数字开头,当函数从str 中读到非数字字符则结束转换并将结果返回。

返回值:字符串的整数表示形式

code:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <cstdlib>
 6 using namespace std;
 7 const int MAXN = 15;
 8 typedef long long LL;
 9 char str[MAXN];
10 char ups[MAXN];
11 char dws[MAXN];
12 
13 LL gcd(LL a, LL b)
14 {
15     return !b ? a : gcd(b, a % b);
16 }
17 
18 int main()
19 {
20     while (scanf(" 0.%[0-9]...", str) == 1)
21     {
22         int len = strlen(str);
23         if (str[0] == '0' && len == 1) break;
24         LL ansu, ansd; // 分别存储分子和分母
25         ansd = 1000000000000;
26         for (int i = 0; i < len; ++i)
27         {
28             strncpy(ups, str, i);   // 拷贝前i个字符到ups作为非循环部分
29             ups[i] = 0;             // 添加字符串结束符
30             strcpy(dws, str + i);   // 从第i个字符开始拷贝给dws(包括字符串结束符),作为循环部分
31             int lu = strlen(ups);
32             int ld = strlen(dws);
33             LL up = atoi(ups) * (pow(10, ld) - 1) + atoi(dws); // 计算分子(atoi函数将字符串转换成一个整数并返回结果)
34             LL down = pow(10, lu + ld) - pow(10, lu);          // 计算分子
35             LL d = gcd(down, up);  // 计算最大公约数,分子分母约分
36             up /= d;
37             down /= d;
38             if (down < ansd)    // 更新分子和分母
39             {
40                 ansu = up;
41                 ansd = down;
42             }
43         }
44         printf("%lld/%lld\n", ansu, ansd);    // 输出分母最小的结果
45     }
46     return 0;
47 }

 

posted @ 2015-07-18 11:20  jasaiq  阅读(372)  评论(0编辑  收藏  举报