搜到的许多题解我感觉讲的有点笼统有点不好理解,所以我自己来写一个。
我们想,在小学我们学过a / b = c ···d,a是被除数,b是除数,d是余数。
再回想小学老师讲的循环小数,我们笔算除法的时候都是用竖式除法一步步来算:商最大能除得了当前位数的最大的(1-9)除不动就商0进位(乘10再试)
例:


此时2就是商,1就是余数,现在商完一位,进位再除

这时候就相当于拿10来除

这时候就得到我们要求的结果。
补充一句,要求小数肯定是没有余数的,我们现在马上就要用这种余数的性质来得到小数点后面的结果。
现在我们来模拟当时判断循环小数的情形:
先说结论,余数的循环肯定要优先出现于商的循环

#include <iostream>
#include <cstring>
using namespace std;
// 回想竖式除法,当循环节出现的时候,我们的余数循环是优先于商循环的
int t;
int n;
int time[100000 + 10]; //存次数的数组也要开到与n一样大,不能单单统计0-9的出现次数。因为当n很大的时候,a需要攒到很大的时候才能除得了n(回想一下竖式除法)
int a;
void chu(int n){
a = 1;
time[1] = 1; //要把1出现的次数记为1,因为我们一开始就是用1*10/n来进行第一个的除法操作,如果后面又出现了1,就说明又回到最初的起点就是开始循环了
printf("0.");
while(a){ //不能写while(1),因为如果最后不是循环小数的话,最后一定是可以整除的
a *= 10;
printf("%d",a / n);
a %= n;
if (time[a] != 0)
break;
else
time[a] = 1;
}
printf("\n");
}
int main(){
cin >> t;
while(t--){
cin >> n;
if(n < 0){
n = -n;
printf("-");
chu(n);
}
else if(n == 1){
printf("1\n");
}
else if(n > 1){
chu(n);
}
memset(time, 0, sizeof(time));
}
return 0;
}
3981

被折叠的 条评论
为什么被折叠?



