小数转化为分数
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1717
题意:把小数转化为分数,循环部分用()表示。
void Work(char str[])
{
int len = strlen(str);
LL a = 0;
LL b = 0;
int cnt1 = 0;
int cnt2 = 0;
for(int i=2;i<len;i++)
{
if(str[i] == '(') break;
a = a * 10 + str[i] - '0';
cnt1++;
}
bool flag = false;
for(int i=2;i<len;i++)
{
if(str[i] == '(' || str[i] == ')')
{
flag = true;
continue;
}
b = b * 10 + str[i] - '0';
cnt2++;
}
cnt2 -= cnt1;
LL p = b - a;
LL q = 0;
if(!flag)
{
p = b;
q = 1;
cnt2 = 0;
}
for(int i=0;i<cnt2;i++)
q = q * 10 + 9;
for(int i=0;i<cnt1;i++)
q = q * 10;
LL g = gcd(p,q);
p /= g;
q /= g;
cout<<p<<"/"<<q<<endl;
}
分数转化为小数
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2522
定理1:有理数a/b (其中0<a<b,(a,b)=1)能表示成纯循环小数的充要条件是(b,10)=1
定理2:有理数a/b, 0<a<b, (a,b)=1,b=(2^α)*(5^β)*b1, (b1,10)=1,b1不等于1,α,β不全为零,则a/b可以表示为纯
循环小数,其不循环的位数为u = max(α,β)
定理1的证明参见 薛利敏的论文 纯循环小数循环节的规律
定理2的证明:通过把b拆成2部分,(10^u)*b1,当然分子a要相应乘以(2^(u-α))*(5^(u-β))即为a'=a*(2^(u-α))*(5^(u-β)),这样对于a'/b1先化成真分数,大于1的部分就是不循环小数部分,小于1的是纯循环小数部分,得证。
void Work(int n)
{
bool flag = 0;
int ans[N],f[N];
memset(ans,0,sizeof(ans));
memset(f,0,sizeof(f));
if(n < 0)
{
n = -n;
flag = 1;
}
int k = 1;
f[k] = 1;
int cnt = 0;
while(k && n != 1)
{
k *= 10;
ans[cnt++] = k / n;
k %= n;
if(f[k]) break;
f[k] = 1;
}
if(flag) printf("-");
if(n == 1) puts("1");
else
{
printf("0.");
for(int i=0;i<cnt;i++)
printf("%d",ans[i]);
puts("");
}
}