问题:
给定两个数a、b,找出a/b的循环节,并按照指定格式输出。比如a=1、b=3,则输出0.(3),即用括号包含循环节。
解法:
USCAO 2.4.5中的题 Fractions to Decimals
有一个tricky的解法,用分母中2的因子个数减去分子中2的因子个数,同样用分母中5的因子个数减去分子中5的因子个数,去两者这两者个数的最大值,这个就是分数的非循环部分的长度,这样偏移后,后面就是循环部分,直到重复。
算法如下:
































































































一、纯循环小数化分数
从小数点后面第一位就循环的小数叫做纯循环小数。怎样把它化为分数呢?看下面例题。
把纯循环小数化分数:
纯循环小数的小数部分可以化成分数,这个分数的分子是一个循环节表示的数,分母各位上的数都是9。9的个数与循环节的位数相同。能约分的要约分。
二、混循环小数化分数
不是从小数点后第一位就循环的小数叫混循环小数。怎样把混循环小数化为分数呢? 把混循环小数化分数。
(2)先看小数部分0.353
一个混循环小数的小数部分可以化成分数,这个分数的分子是第二个循环节以前的小数部分组成的数与小数部分中不循环部分组成的数的差。分母的头几位数是9,末几位是0。9的个数与循环节中的位数相同,0的个数与不循环部分的位数相同。
三、循环小数的四则运算
循环小数化成分数后,循环小数的四则运算就可以按分数四则运算法则进行。从这种意义上来讲,循环小数的四则运算和有限小数四则运算一样,也是分数的四则运算。
有限小数化成分数直接将小数点去掉,分母对应化成十百千万等。再约分。
例如:0.333.....=3/9=1/3
0.214214214214214....=214/999
简单说每一个循环节为分子,循环节有几位数分母就写几个9
0.3333......循环节为3 0.214.....循环节为214
0.52525252....循环节为52,所以0.525252...=52/99
0.35....=35/99
给定两个数a、b,找出a/b的循环节,并按照指定格式输出。比如a=1、b=3,则输出0.(3),即用括号包含循环节。
USCAO 2.4.5中的题 Fractions to Decimals
有一个tricky的解法,用分母中2的因子个数减去分子中2的因子个数,同样用分母中5的因子个数减去分子中5的因子个数,去两者这两者个数的最大值,这个就是分数的非循环部分的长度,这样偏移后,后面就是循环部分,直到重复。
算法如下:
转载于:https://www.cnblogs.com/clive/archive/2009/10/28/Circular_decimal_fraction_USCAO_2_4_5.html
循环小数化分数口诀2019-11-25 14:23:32文/颜雨
循环小数化分数口诀:将纯循环小数改写成分数,分子是一个循环节的数字组成的数;分母各位数字都是9,9的个数与循环节中的数字的个数相同。
纯循环小数化为分数:将纯循环小数改写成分数,分子是一个循环节的数字组成的数;分母各位数字都是9,9的个数与循环节中的数字的个数相同。例如:0.111...=1/9、0.12341234...=1234/9999
混循环小数化为分数:将混循环小数改写成分数,分子是不循环部分与第一个循环节连成的数字组成的数,减去不循环部分数字组成的数之差;分母的头几位数字是9,末几位数字是0,9的个数跟循环节的数位相同,0的个数跟不循环部分的数位相同。例如:0.1234234234…=(1234-1)/9990
0.55889888988898...=(558898-55)/999900。
两个整数相除,如果得不到整数商,会有两种情况:一种,得到有限小数;另一种,得到无限小数。从小数点后某一位开始依次不断地重复出现前一个或一节数字的十进制无限小数,叫做循环小数,其中依次循环不断重复出现的数字叫循环节。
对于一个分数(不一定是最简形式),给出它的小树形式,如果小数有循环节的话,把循环节放在一对圆括号中.
例如,1/4 =0.25,1/3=0.3333写成0.(3),1/7= 0.142857142857...写成0.(142857)。如果结果是一种整数xxx,则用xxx.0 等表示整数xxx。
输入包括一行,包括被空格分隔开的分子N和分母D(第一个是N,第二个是D)。
输出包括一行,为转换后的小数形式。
样例输入
45 56
样例输出
0.803(571428)
模拟除法的计算过程
整数部分:a/b
小数部分:
①mod = a%b;
②小数 = (mod*10) / b;
③mod = (mod*10)%b;
循环②③步,当出现重复的余数的时候,也就是循环节出现了
C++
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b;
scanf("%d%d",&a,&b);
if(a%b==0)
{
printf("%d.0\n",a/b);
return 0;
}
map<int,int> m;//标记余数
vector<int>rem;//余数
rem.clear();
vector<int> v;//商数
v.clear();
int pos=-1;
while(true){
v.push_back(a/b);
int x=a%b;//余数
if(x==0) break;
if(m[x]) {//map缺省情况下为0
pos=find(rem.begin(),rem.end(),x)-rem.begin();
break;
}
rem.push_back(x);
m[x]=1;
a=x*10;
}
printf("%d.",v[0]);
for(int i=1;i<v.size();i++){
if(i==pos+1)
printf("(");
printf("%d",v[i]);
}
if(pos>=0) printf(")");
return 0;
}
Java
import java.util.List;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Map;
import java.util.HashMap;
public class Main {
static void f(int a,int b) {
ArrayList<Integer> rem=new ArrayList<Integer>();//余数
ArrayList<Integer> v=new ArrayList<Integer>();//商数
HashMap<Integer,Integer> m=new HashMap<Integer,Integer>();//标记余数
int pos=-1;
while(true) {
v.add(a/b);//商数
int x=a%b;//余数
if(x==0) break;
if(m.containsKey(x)) {//判断余数是否存在
pos=rem.indexOf(x);//查找重复余数所在的位置
break;
}
m.put(x,1);//标记
rem.add(x);//将余数添加到动态数组中
a=x*10;
}
System.out.print(v.get(0)+".");
for(int i=1;i<v.size();i++) {
if(pos+1==i)
System.out.print("(");
System.out.print(v.get(i));
}
if(pos>=0)
System.out.println(")");
}
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
int a=cin.nextInt();
int b=cin.nextInt();
if(a%b==0) {
System.out.println(a/b+".0");
}else {
f(a,b);
}
cin.close();
}
}