传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1717
整数化小数,不循环的小数容易化。对于循环小数化分数原理如下:
⑴ 把0.4747……和0.33……化成分数。
例1: 0.4747……×100=47.4747……
0.4747……×100-0.4747……=47.4747……-0.4747……
(100-1)×0.4747……=47
即99×0.4747…… =47
那么 0.4747……=47/99
例2: 0.33……×10=3.33……
0.33……×10-0.33……=3.33…-0.33……
(10-1) ×0.33……=3
即9×0.33……=3
那么0.33……=3/9=1/3
由此可见, 纯循环小数化分数,它的小数部分可以写成这样的分数:纯循环小数的循环节最少位数是几,分母就是由几个9组成的数;分子是纯循环小数中一个循环节组成的数。
⑵把0.4777……和0.325656……化成分数。
例1:0.4777……×10=4.777……①
0.4777……×100=47.77……②
用②-①即得:
0.4777……×90=47-4
所以, 0.4777……=43/90
例2:0.325656……×100=32.5656……①
0.325656……×10000=3256.56……②
用②-①即得:
0.325656……×9900=3256.5656……-32.5656……
0.325656……×9900=3256-32
所以, 0.325656……=3224/9900
根据原理,易写出代码。
#include <stdio.h> #include <string.h> int gcd(int m,int n){ return n==0?m:gcd(n,m%n); } int main(){ char str[20];//输入的数据 char str_temp[20];//临时变量 int i,gcd_value;//临时变量 int n;//样例个数 int fenzi,fenmu;//附加变量:输入数据转换成的小数 int num,num_bxh;//附加变量:str和str的不循环部分转换成的数字型 int len1,len2;//附加变量:非循环部分进位数和循环部分进位数 scanf("%d",&n); while (n--){ scanf("%s",str); len1=len2=1; for (i=2;str[i]!='('&&str[i]!='\0';i++){ len1*=10;///len1=10的 非循环部分位数 次方 str_temp[i-2]=str[i]; } str_temp[i-2]='\0'; if(strlen(str_temp)==0) num_bxh=0; else sscanf(str_temp,"%d",&num_bxh);//将非循环部分转换成数字 //若存在循环小数部分 if(str[i]=='('){ for (i++;str[i]!=')';i++){ str_temp[i-3]=str[i];//将循环部分添加到非循环部分尾部 len2 *=10; } str_temp[i-3]='\0';//替换')'为结束符 sscanf(str_temp,"%d",&num);//将全部字符串转换成数字 fenmu = len1*len2-len1;//大进位数 减 一个循环单元的小进位数 fenzi = num-num_bxh;//非循环和循环部分的整数 减去 非循环部分的整数 gcd_value=gcd(fenzi,fenmu); printf("%d/%d\n",fenzi/gcd_value,fenmu/gcd_value); } //若不存在循环小数部分 else { fenzi = num_bxh;//非循环部分整数 fenmu= len1;//分母为小数变整数需要乘以的位数 gcd_value = gcd(fenzi,fenmu); printf("%d/%d\n",fenzi/gcd_value,fenmu/gcd_value); } } }