POJ 1930 Dead Fraction

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;
}

题解参考这里写链接内容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值