算法竞赛入门经典(第二版)P59 习题3-8 循环小数 UVa202
这道题写的时候,第一次感觉到数学、算法的某种魅力。
刚开始一直想是否存在某种函数可以得到整数相除的,小数点后指定位数的结果,后发现不可行。然后在草稿上写除法的计算过程时,发现对于除法a / b,余数只有b种(0 ~ b-1),所以记录每次除法运算的余数,当余数相等,则代表开始循环。
#include<stdio.h>
#include<string.h>
// 余数等,开始循环
// 余数有 b 种(0 ~ b-1) ,所以循环串最长为 b
int main(){
int a, b;
while(scanf("%d %d", &a, &b) != EOF){ //scanf("%d %d", &a, &b) == 2
int c = 0; // 余数
int d = 0; // 结果
int a1 = a; // 被除数
int b1[b]; // 余数串
int b2[b]; // 结果串
int i = 0, j = 0;
int m; // 标记开始循环的下标位置
int f1 = 0; // 循环串是否为0
// 1 判断
while(1){
b1[i++] = a1 % b;
b2[j++] = a1 / b;
if(b1[i-1] == 0){ // 余数为0,循环串为0,跳出循环
f1 = 1;
break;
}
int flag = 0;
for(m = 0; m < j-1; m++){
if(b1[m] == b1[j-1]){ // 余数等,找到循环串,跳出循环
flag = 1;
break;
}
}
if(flag) break;
a1 = b1[i-1] * 10;
}
// 2 输出
printf("%d/%d = %d.", a, b, b2[0]);
int n = 1;
while(n < i){
if(!f1 && n == m+1) printf("(");
if(n > 50){
printf("...");
break;
}
printf("%d", b2[n++]);
}
if(f1 && n == i) printf("(0)\n");
else printf(")\n");
printf(" %d = number of digits in repeating cycle\n\n", f1?1:i - 1 - m); // 使用 ? : 简化语句
}
return 0;
}