杭电hdu1717 - 小数化分数2


传送门: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);
		}
	}

}





  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值