声明:摘选自“ 算法竞赛入门经典(第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取整;即
读取循环节长度就设置一个标志位,循环一次,标志位就 +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
}