无限循环小数POJ1930

题意:给定一个无限循环小数,求其分数形势,要求分母最小

分析:看了别人的题解才做出来的,将无限循环小数转化成分数,分为纯循环和混循环两种形式。

     (1)对于纯循环:用9做分母,有多少个循环数就几个9,比如0.3,3的循环就是9分之3,0.654,654的循环就是999分之654, 0.9,9的循环就是9分之1,以此类推。

      (2)混循环:用9和0做分母,首先有几个循环节就几个9,接着有几个没加入循环的数就加几个0,再用小数点后面的数减 没加入循环的数,比如0.43,3的循环,有一位数没加入循环,就在9后面加一个0做分母,再用43减4做分子,得 90分之39,0.145,5的循环就用9后面加2个0做分母,再用145减14做分子,得900分之131,0.549,49的循环,就 用99后面加1个0做分母,用549减5做分子,最后得990分之545,以此类推,能约分的要化简。

本题没有说明循环节在哪一位,因此每一位进行枚举,取分母最小的就是所求 ,注意学会STL中String的用法。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 #include <vector>
 6 #include <algorithm>
 7 #include <set>
 8 #include <map>
 9 #include <bitset>
10 #include <cmath>
11 #include <queue>
12 #include <stack>
13 using namespace std;
14 string s;
15 long long gcd(long long a,long long b)
16 {
17     if(b==0)   return a;
18     return gcd(b,a%b);
19 }
20 int main()
21 {
22     while(cin>>s)
23     {
24         if(s=="0")  break;
25         string digit=s.substr(2,s.length()-5);
26         int n=digit.length();
27         long long m=atoi(digit.c_str());  //小数点后面的数
28         long long fmmin,fzmin;
29         fmmin=1<<30;
30         for(int i=1;i<=n;i++)
31         {
32             string cnt=digit.substr(0,n-i);
33             long long res=m-atoi(cnt.c_str()); //分子
34             long long ans=pow(10,n)-pow(10,n-i);  //分母
35             long long num=gcd(res,ans);
36             res/=num;     //最简形式
37             ans/=num;
38             if(fmmin>ans)
39             {
40                 fmmin=ans;
41                 fzmin=res;
42             }        
43         }
44         cout<<fzmin<<"/"<<fmmin<<endl;
45     }
46     return 0;
47 }
View Code
原文地址:https://www.cnblogs.com/wolf940509/p/5792439.html