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 }