求分数循环节(分数化小数)的算法

问题:

给定两个数a、b,找出a/b的循环节,并按照指定格式输出。比如a=1、b=3,则输出0.(3),即用括号包含循环节。

 

解法:

USCAO 2.4.5中的题 Fractions to Decimals
有一个tricky的解法,用分母中2的因子个数减去分子中2的因子个数,同样用分母中5的因子个数减去分子中5的因子个数,去两者这两者个数的最大值,这个就是分数的非循环部分的长度,这样偏移后,后面就是循­环部分,直到重复。

算法如下:


#include 
<iostream>

using namespace std; 
typedef 
long long int64; 

int colcount=0;

int numBeforeRepeat(int n,int d)
{
    
int c2=0,c5=0;
    
if(n==0return 1;
    
while(d%2==0){d/=2;c2++;}//dominator 中2的个数
    while(d%5==0){d/=5;c5++;}//dominator 中5的个数
    while(n%2==0){n/=2;c2--;}//can go to negative
    while(n%5==0){n/=5;c5--;}//can go to negative
    if(c2>c5) {
        
if(c2>0return c2;
        
else return 0;
    }
 else {
        
if(c5>0return c5;
        
else return 0;
    }

}


void print(char c)
{
    
if(colcount==76{
        cout
<<endl;
        colcount
=0;
    }

    cout
<<c;
    colcount
++;
}


void print(int n)
{
    
if(n>=10) print(n/10);
    print((
char)('0'+(n%10)));
}
 

int main()
{
    
int n,d;
    cin
>>n>>d;
    print(n
/d);
    print(
'.');
    n
=n%d;
    
int m=numBeforeRepeat(n,d);
    
for(int i=0;i<m;i++{
        n
*=10;
        print(n
/d);
        n
%=d;
    }

    
int r=n;
    
if(r!=0{
        print(
'(');
        
do {
            n
*=10;
            print(n
/d);
            n
%=d;
        }
 while(n!=r);
        print(
')');
    }

    cout
<<endl;
    
return 0;
}

 

 

posted on 2009-10-28 00:07  CLive Studio  阅读(...)  评论(...编辑  收藏

导航

统计