求分数循环节(分数化小数)的算法
问题:
给定两个数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==0) return 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>0) return c2;
else return 0;
} else {
if(c5>0) return 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 阅读(1376) 评论(0) 编辑 收藏 举报