题目链接:http://poj.org/problem?id=1930
题目大意:
给一个无限循环小数(循环节不知),要求你输出当该小数所化成的最简分数分母最小时所对应的最简分数。
AC思路:
完全没思路,思路来源于:码农场(http://www.hankcs.com/program/cpp/poj-1930-dead-fraction.html)。
先来一点小学奥数知识。。。“连小学生都不如”说的就是我这种ORZ
纯循环
用9做分母,有多少个循环数就几个9,比如0.3,3的循环就是9分之3,0.654,654的循环就是999分之654, 0.9,9的循环就是9分之9(1),以此类推。
混循环
先来看几个例子
例:把混循环小数0.228‘化为分数:
解:0.228‘
=[(228/1000)+8/9000)]
=228/(900+100)+8/9000
=[(228/900)-(228/9000)]+(8/9000)
=(228/900)+[(8/9000)-(228/9000)]
=(228/900)-(22/900)
=(228-22)/900
=206/900
=103/450;
例:把混循环小数0.123‘68‘化成分数:
解:0.123‘68‘=(0.12368+0.00000‘68‘)
=(12368/100000)+(68/9900000)
=[(12368/99000)-(12368/990000)]+(68/9900000)
=(12368/99000)+[(68/9900000)-(12368/9900000)]
=(12368/99000)-(12300/9900000)
=(12368-123)/99000
公式
用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,以此类推,能约分的要化简。
此外其实就没什么了。。。、
AC代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <string> 4 #include <cctype> 5 #include <cmath> 6 #include <cstring> 7 #include <cstdlib> 8 #include <algorithm> 9 #include <vector> 10 using namespace std; 11 typedef long long ll; 12 typedef pair<ll,ll> P; 13 14 vector<P> q; 15 int gcd(ll a,ll b){ 16 if(b==0) return a; 17 return gcd(b,a%b); 18 } 19 bool cmp(const P &a, const P &b){ 20 return a.second<b.second; 21 } 22 int main(){ 23 string st; 24 while(cin>>st){ 25 q.clear(); 26 if(st=="0") break; 27 string num=st.substr(2,st.size()-5); 28 string temp; 29 for(int i=1;i<=num.size();i++){ 30 temp.clear(); 31 int j; 32 for(j=0;j<i;j++) 33 temp+=‘9‘; 34 for(;j<num.size();j++) 35 temp+=‘0‘; 36 ll ma=atoi(temp.c_str()); 37 string tt=num.substr(0,num.size()-i); 38 ll son=atoi(num.c_str())-atoi(tt.c_str()); //string转化成int的技巧:atoi(string.c_str()) 39 ll g=gcd(ma,son); 40 q.push_back(make_pair(son/g,ma/g)); 41 } 42 sort(q.begin(),q.end(),cmp); 43 cout<<q[0].first<<‘/‘<<q[0].second<<endl; 44 st.clear(); 45 } 46 return 0; 47 }