算法的乐趣c/c++ —— 1.2.1入门习题

声明:摘选自“ 算法竞赛入门经典(第2版)”作者:  刘汝佳  /  陈锋   ISBN:9787302291077

循环小数

输入整数a和b(0≤a≤3000,1≤b≤3000),输出a/b的循环小数表示以及循环节长度。 例如a=5,b=43,小数表示为0.(116279069767441860465),循环节长度为21。

解题思路:

5/43,就算是double类型的变量小数点后也只有几位数字,完全不能达到我们的要求。那么我们就采用以小见大的方法,50/43、500/43、5000/43、、、这样肯定能够得到我们需要的答案。但是需要将除数扩大多少倍才可以呢?我们可以根据算数运算规则来看:5/43 ≈ 0.116。0=5/43 取整;  1=(5*10%43)*10 /43 就是5扩大10倍取余43即70/43取整;即

\frac{5}{43} => \tfrac{5*10}{43} => \tfrac{43+7}{43} => 1+\tfrac{7*10}{43} => 1+1+\tfrac{27*10}{43} => 1+1+6+\tfrac{12*10}{43}

读取循环节长度就设置一个标志位,循环一次,标志位就 +1 。如何结束循环呢?就是看余数,如果后面的余数等于最初第一个余数,说明接下来就会重复刚刚的计算过程了,那么这就说明我们已经找到第二个循环了。可以结束计算过程了。

#include<stdio.h>
int main()
{
	int a, b, H, L, m, i=0;    //a,b为输入的数字,H为a/b的整数部分,L为a%b的余数部分, m为标志位, i用于记录循环节长度 
	scanf("%d%d", &a, &b);     //输入数字a,b 
	printf("%d.(", a/b);       //先打印整数部分加上一个半括号。例如: 0.( 
	L = a % b;                 //L初始等于a%b。 后续会继续对L进行赋值,以便不断进行除法操作  
	m = L;                     //将m赋值L,如果后续出现m得值等于不断赋值后的L,说明我们已经开始进入下一个循环了 
	while(1)
	{
		H = L*10 / b;          //H用于存放需要打印的整数部分,5/43=0.1,但是打印不出0.1怎么办?那就将5扩大10倍打印 1, 
		L = L*10 % b;          //L已经取余一次了,再取余肯定还是不变的,为了求取下一位数字,那么就需要将小数点右移一位,即扩大10倍 
		printf("%d", H);
		i += 1;                // i用于记录小数点后的位数 
		if(m==L) break;        //如果出现m得值等于不断赋值后的L,说明我们已经开始进入循环了 ,这就是我们结束while的条件 
	}
	printf(") %d",i);          //打印整一个半括号跟循环节长度。例如: ) 21 
} 


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值