poj1930
题目意思:给定一个无限循环小数,把它转换成分数。
这个需要一定姿势水平。。。
纯循环
9做分母,有几个循环数,就有几个9,例如0.3就是9分之3,0.654就是999分之654。。等等
混循环
把0.228转换成分数(8是循环节)
=[(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.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,以此类推,能约分的要化简。
题目没说循环小数从哪一点开始,直接枚举即可。
#include <vector>
#include <iostream>
#include <cstdio>
#include <string>
#include <limits>
#include <cstdlib>
using namespace std;
typedef unsigned long long ULL;
ULL gcd(ULL a,ULL b){
return (b==0)?a:gcd(b,a%b);
}
ULL pow(int x){
ULL res=1;
for(int i=0;i<x;i++){
res*=10;
}
return res;
}
int main(){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
cin.tie(0);
ios::sync_with_stdio(false);
string line;
while(cin>>line){
if(line=="0"){
break;
}
string str=line.substr(2,line.size()-5);
unsigned int length=str.size();
ULL n=atoi(str.c_str());
if(n==0){
cout<<"0/1"<<endl;
continue;
}
ULL min_x=numeric_limits<ULL>::max();
ULL min_y=0;
for(int i=1;i<=length;i++){
string first=str.substr(0,length-i);
ULL x=pow(length)-pow(length-i);
ULL y=n-atoi(first.c_str());
ULL d=gcd(x,y);
x/=d;
y/=d;
if(min_x>x){
min_x=x;
min_y=y;
}
}
cout<<min_y<<"/"<<min_x<<endl;
}
return 0;
}
题解参考这里写链接内容