杭电地址:http://acm.hdu.edu.cn/game/entry/problem/show.php?chapterid=2§ionid=1&problemid=12
小数化分数2 |
| Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) |
| Total Submission(s): 1984 Accepted Submission(s): 711 |
|
Problem Description
Ray 在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢?
请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。 |
|
Input
第一行是一个整数N,表示有多少组数据。
每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。 |
|
Output
对每一个对应的小数化成最简分数后输出,占一行。
|
|
Sample Input
3 0.(4) 0.5 0.32(692307) |
|
Sample Output
4/9 1/2 17/52 |
首先须知:小数有 有限和无限之分,其中无限小数中,又分无限循环和无限不循环小数,能用分数表示的当然只有有限小数和无限循环小数。
有限小数就简单了,无论多少只要小数点后面的 除以 10的n次方就行了,约分一下就完事了。
对于无限循环小数分两种,这里举例说明:
⑴ 把0.4747……化成分数。
0.4747……×100=47.4747……
0.4747……×100-0.4747……=47.4747……-0.4747…… 注:因为是无限小数,所以小数点后趋向于无穷远处的 相减极限为零了
(100-1)×0.4747……=47 //提取公因式0.4747
即99×0.4747…… =47
那么 0.4747……=47/99
(2)把0.325656……化成分数,(道理同上)
0.325656……×100=32.5656……①
0.325656……×10000=3256.56……②
用②-①即得:
0.325656……×9900=3256.5656……-32.5656……
0.325656……×9900=3256-32
所以, 0.325656……=3224/9900
代码(同样参考的是网上同学的代码):
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
int gcd (int a, int b)
//辗转相除法。
{
int r;
while (b)
{
r=a%b;
a=b;
b=r;
}
return a;
}
int main(int argc, char *argv[])
{
int numcase;
char s[20];
cin>>numcase;
while (numcase--)
{
cin>>s;
int a, b, a1, b1, a2, b2;
int lena=0, m, len, i;
len=strlen(s)-1;
for (i=2; i<len && s[i]!='('; i++)
lena++;
if (i==len) //有限小数情况
{
b=0; a=1;
for (i=2; i<=len; i++)
{
b=b*10+s[i]-'0';
a=10*a;
}
}
else //无限循环小数情况
{
/*
⑵把0.4777……和0.325656……化成分数。
想1:0.4777……×10=4.777……①
0.4777……×100=47.77……②
用②-①即得:
0.4777……×(100-10)=47-4 所以, 0.4777……=43/90
*/
b1=0; a1=1;
for (i=0; i<lena; i++)
{
b1=b1*10+s[i+2]-'0';
a1=10*a1;
}
b2=0; a2=1;
for (i=2; i<len; i++)
{
if(s[i]<='9'&&s[i]>='0')
{
b2=b2*10+s[i]-'0';
a2=a2*10;
}
}
a=a2-a1;
b=b2-b1;
}
m=gcd(a, b);
cout<<b/m<<"/"<<a/m<<endl;
}
//system("PAUSE");
return EXIT_SUCCESS;
}

2008

被折叠的 条评论
为什么被折叠?



