小數轉化爲分數
題目: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("");
}
}