UVa 202 Repeating Decimals(抽屉原理)
Repeating Decimals
紫书第3章,这哪是模拟啊,这是数论题啊
【题目链接】Repeating Decimals
【题目类型】抽屉原理
&题解:
n除以m的余数只能是0~m-1,根据抽屉原则,当计算m+1次时至少存在一个余数相同,即为循环节;存储余数和除数,输出即可。
上面是我查到的,现在让我解释一下:
比如5/43,先是要模拟除法运算,第一步50/43 余7;第二步,70/43 于27... 这样一直取余下去,肯定不会超过43次,就会有余数相同的情况,有相同情况就是找到循环节了.那么循环节的长度也就是这个数的位置减去上一次出现这个数的位置的值了.
&代码:
#include <cstdio>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>
using namespace std;
#define INF 0x3f3f3f3f
using ll=long long;
const int maxn= 3e3 +9;
int r[maxn],u[maxn],a,b;
int main()
{
while(~scanf("%d%d",&a,&b)){
int aa=a;
memset(u,0,sizeof(u));
memset(r,0,sizeof(r));
int cnt=0;
r[cnt++]=a/b;
a=a%b;
while(!u[a]&&a){
u[a]=cnt;
r[cnt++]=10*a/b;
a=10*a%b;
}
printf("%d/%d = %d.",aa,b,r[0]);
for(int i=1;i<cnt&&i<=50;i++){
if(i==u[a])printf("(");
printf("%d",r[i]);
}
if(cnt>50) printf("...");
if(!a) printf("(0"),cnt=u[a]+1;
printf(")\n");
printf(" %d = number of digits in repeating cycle\n\n",cnt-u[a]);
}
return 0;
}