您的位置:首页 > 其它

(hdu step 2.1.8)小数化分数2(小数化分数——包括了循环小数化分数的情况)

2015-02-23 11:12 246 查看
题目:

小数化分数2

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2783 Accepted Submission(s): 993
 
[align=left]Problem Description[/align]Ray 在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢?
请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。
 
[align=left]Input[/align]第一行是一个整数N,表示有多少组数据。
每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。
 
[align=left]Output[/align]对每一个对应的小数化成最简分数后输出,占一行。 
[align=left]Sample Input[/align]
3
0.(4)
0.5
0.32(692307)
 
[align=left]Sample Output[/align]
4/9
1/2
17/52
 
 
[align=left]Source[/align]2007省赛集训队练习赛(2) 
[align=left]Recommend[/align]lcy
题目分析:
               简单题。小数化分数。其中这里的的“小数”包括了循环小数。循环小数可以分为以下两种:
1)纯循环小数。纯循环小数没有非循环节部分,全部由循环节组成。它在化为分数的时候有以下规律:
分子=循环节上的数字
分母=9.....(9的个数取决于循环节的位数)

2)非纯循环小数。

分子=非循环部分*循环节需要放大的倍数+循环节上的数字-非循环部分;
分母=999...000...(其中9的个数取决于循环节的位数,0的个数取决于非循环部分的位数)

以下的知识有助于帮你理解以上的规律:
1、众所周知,有限小数是十进分数的另一种表现形式,因此,任何一个有限小数都可以直接写成十分之几、百分之几、千分之几……的数。那么无限小数能否化成分数? 

首先我们要明确,无限小数可按照小数部分是否循环分成两类:无限循环小数和无限不循环小数。无限不循环小数不能化分数,这在中学将会得到详尽的解释;无限循环小数是可以化成分数的。那么,无限循环小数又是如何化分数的呢?由于它的小数部分位数是无限的,显然不可能写成十分之几、百分之几、千分之几……的数。其实,循环小数化分数难就难在无限的小数位数。所以我就从这里入手,想办法“剪掉”无限循环小数的“大尾巴”。策略就是用扩倍的方法,把无限循环小数扩大十倍、一百倍或一千倍……使扩大后的无限循环小数与原无限循环小数的“大尾巴”完全相同,然后这两个数相减,“大尾巴”不就剪掉了吗!我们来看两个例子:

⑴    把0.4747……和0.33……化成分数。

想1:        0.4747……×100=47.4747……   

0.4747……×100-0.4747……=47.4747……-0.4747……

(100-1)×0.4747……=47

即99×0.4747…… =47 

那么  0.4747……=47/99

想2: 0.33……×10=3.33……

0.33……×10-0.33……=3.33…-0.33……

(10-1) ×0.33……=3

即9×0.33……=3

那么0.33……=3/9=1/3

由此可见, 纯循环小数化分数,它的小数部分可以写成这样的分数:纯循环小数的循环节最少位数是几,分母就是由几个9组成的数;分子是纯循环小数中一个循环节组成的数。

⑵把0.4777……和0.325656……化成分数。

想1:0.4777……×10=4.777……①

0.4777……×100=47.77……②

用②-①即得: 

0.4777……×90=47-4

所以, 0.4777……=43/90

想2: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

将纯循环小数改写成分数,分子是一个循环节的数字组成的数;分母各位数字都是9,9的个数与循环节中的数字的个数相同.

  将混循环小数改写成分数,分子是不循环部分与第一个循环节连成的数字组成的数,减去不循环部分数字组成的数之差;分母的头几位数字是9,末几位数字是0,9的个数跟循环节的数位相同,0的个数跟不循环部分的数位相同.

2、(1)纯循环小数(仅指整数部分为0的)化成分数时,分数的分母由9组成,9的个数等于一个循环节的位数,分子是由一个循环节的各位数字组成。
如:0,234234234....=234/999
0.111111=1/9 

(2)非纯循环小数化成分数时,分母由9和0组成,其中9的个数等于一个循环节的位数,0的个数等于非循环部分的位数。分子是从小数点后的第一位到第一个循环节的末位组成的数减去非循环部分。
如:0,76345345345。。。。=(76345-76)/99900
    0.0243434343.........=(243-2)/9900
  0.811111。。。。=(81-8)/90=73/90

代码如下:
/*
* e2.cpp
*
* Created on: 2015年2月23日
* Author: Administrator
*/

#include <iostream>
#include <cstdio>

using namespace std;

/**
* 求最大公约数
*/
int gcd(int a,int b){
int temp;
while(b != 0){
temp = b;
b = a%b;
a = temp;
}

return a;
}

/**
* 将小数转换成相应的最简分数
* str:小数的字符串
*/
void xiaoshu2Fenshu(string str){
int s1 = 0;//小数的非循环部分
int p1 = 1;//小数的非循环部分放大成整数所需要扩大的倍数
int s2 = 0;//小数的循环部分
int p2 = 1;//将小数的循环部分放大成整数所需要扩大的倍数

int length = str.length();
int i = 0;
while(str[i] != '.' && i < length){//找到小数的非循环部分的起始位置
i++;
}
i++;

while(str[i] != '(' && i < length){//获取小数的非循环部分
s1 = s1*10 + str[i] - '0';
p1 *= 10;
i++;
}
i++;

while(str[i] != ')' && i < length){//获取小数的循环部分
s2 = s2*10 + str[i] - '0';
p2 *= 10;
i++;
}

int t1;//分子
int t2;//分母
int t;//分子与分母的最大公约数,用于求最简分数
if(s2 != 0){//如果循环部分非0,则表明该小数是循环小数
t1 = s1*p2+s2 - s1;//计算循环小数画成分数以后的分子
t2 = (p2-1)*p1;//计算分母
}else{//否则weight普通分数
t1 = s1;//普通小数的分子就是非循环部分
t2 = p1;//普通小数的分母就是分循环部分需要扩大的倍数
}

t = gcd(t1,t2);//求分子和分母的最大公约数。用于求最简分数

cout << t1/t << "/" << t2/t << endl;
// string result = t1/t + "/" + t2/t;//不要奖整数类型和string类型直接拼接,这样拼接是错误的
// string result = itoa(t1/t) + "/" + itoa(t2/t);
// return result;
}

int main(){
int t;
scanf("%d",&t);
while(t--){
string str;
cin >> str;

xiaoshu2Fenshu(str);

// cout << xunhuanxiaoshu2Fnenhu(str) << endl;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: