uva202:循环小数(循环节+抽屉原理)

题意:

给出两个数n,m,0<=n,m<=3000,输出n/m的循环小数表示以及循环节长度。


思路:

设立一个r[]数组记录循环小数,u[]记录每次的count,用于标记,小数计算可用 r[i]=n*10/m;n=n*10%10 直到n为0或u[n]!=0(找到循环节)

涉及到两个知识点:n/m的余数在0~m-1之间;

    抽屉原理:循环次数最多不超过m+1次

具体见代码。


//求循环节 
#include<cstdio>
#include<cstring>
#define mem(a,b) memset(a,b,sizeof(a))
#define For(i,a,b) for(int i=a;i<=b;i++)
int r[3030],s[3030],u[3030];
int n,m;

int main()
{
    for(;scanf("%d %d",&n,&m)==2;)
    {
        int nn=n,count=0;
        mem(r,0);mem(u,0);
        r[count++]=n/m;
        n%=m;
        while(!u[n]&&n){
            u[n]=count;
            s[count]=n;
            r[count++]=10*n/m;
            n=n*10%m;
        }
        printf("%d/%d=%d.",nn,m,r[0]);
        for(int i=1;i<count&&i<=50;i++) 
        {
        if(n&&s[i]==n) printf("(");//还要想想 
        printf("%d",r[i]);    
        }
        if(!n) printf("(0");
        if(count>50) printf("...");
        printf(")
");
        printf("   %d = number of digits in repeating cycle

",!n?1:count-u[n]);
    }
    return 0; 
} 
原文地址:https://www.cnblogs.com/chendl111/p/5689763.html