zoukankan      html  css  js  c++  java
  • poj 1930 Dead Fraction

    Description

    Mike is frantically scrambling to finish his thesis at the last minute. He needs to assemble all his research notes into vaguely coherent form in the next 3 days. Unfortunately, he notices that he had been extremely sloppy in his calculations. Whenever he needed to perform arithmetic, he just plugged it into a calculator and scribbled down as much of the answer as he felt was relevant. Whenever a repeating fraction was displayed, Mike simply reccorded the first few digits followed by "...". For instance, instead of "1/3" he might have written down "0.3333...". Unfortunately, his results require exact fractions! He doesn't have time to redo every calculation, so he needs you to write a program (and FAST!) to automatically deduce the original fractions. 
    To make this tenable, he assumes that the original fraction is always the simplest one that produces the given sequence of digits; by simplest, he means the the one with smallest denominator. Also, he assumes that he did not neglect to write down important digits; no digit from the repeating portion of the decimal expansion was left unrecorded (even if this repeating portion was all zeroes).

    Input

    There are several test cases. For each test case there is one line of input of the form "0.dddd..." where dddd is a string of 1 to 9 digits, not all zero. A line containing 0 follows the last case.

    Output

    For each case, output the original fraction.

    Sample Input

    0.2...
    0.20...
    0.474612399...
    0
    

    Sample Output

    2/9
    1/5
    1186531/2500000
    

    Hint

    Note that an exact decimal fraction has two repeating expansions (e.g. 1/5 = 0.2000... = 0.19999...).

    Source

    题目给出一个无限循环小数,求分母最小的分数形式,因为循环节具体是多少位是未知的(至少一位),所以枚举,选择分母最小的哪个。
    小数化成分数很容易,循环部分化成分数用解方程法(见注释)。
    代码:
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #define MAX 305
    #define inf 0x3f3f3f3f
    using namespace std;
    /*
    小数转换成分数,分子分母都是整数,所以转化为整数来求
    小数部分分为不循环部分和循环部分,由于不清楚哪部分是循环的,然而题目要求分母最小的,所以枚举不循环的部分剩下的是循环部分
    然后计算结果
    */
    int gcd(int a,int b) {///最大公因数
        return b ? gcd(b,a % b) : a;
    }
    char s[30];
    int main() {
        while(scanf("%s",s) && s[1]) {
            int mina = 1000000000,minb = 1000000000;///初始化分子分母 更新最小
            int dec = 0,c = 0;///dec以整数形式 记录给出的小数部分 c记录位数
            for(int i = 2;s[i] != '.';i ++,c ++) {///遍历字串
                dec = dec * 10 + s[i] - '0';
            }
            for(int num = dec / 10,j = 10,i = 1;i <= c;i ++,j *= 10,num /= 10) {///num为非循环部分,每次减少一位 i是衡量循环部分的位数 j是循环部分的10的幂
                ///下面的计算是根据 假如循环部分是末尾i位 那么 j = 10 ^ i
                ///非循环部分 是 (dec/j) / 10^(c - i)
                ///那么循环部分呢,可以用解方程法,举个例子 x = 0.33333...  10x - x = 3.3333... - 0.33333 = 3 ,9x = 3,x =1 / 3
                ///再比如0.1212... 10^2x - x = 12,x = 12 / 99  也就是说跟循环节以及其位数有关 假如循环节是N,位数是x,那么化成的分数就是N/(10^x - 1)
                ///如果是0.001212...  就是在分母多除以一个10^2罢了,这样这道题的循环部分就有了
                ///即 循环部分是后i位,前c - i位是非循环部分 那么循环部分表示为  dec % j / ((j - 1) * 10^(c - i))
                ///两部分相加通分就是答案   带入 dec % j = dec - dec / j * j   得 (dec - dec / j) / ((j - 1) * 10^(c - i))
                int a = dec - num;///dec - dec / j
                int b = (int)pow(10,c - i) * (j - 1);
                int k = gcd(a,b);
                if(b / k < minb) {
                    mina = a / k;
                    minb = b / k;
                }
            }
            printf("%d/%d
    ",mina,minb);
        }
    }
  • 相关阅读:
    web开发发送短信实现最简单的接口
    2分钟学会ajax 入门ajax必备
    基于注册登陆简单的使用django认证系统
    Django 发送邮件
    关于python开始写项目创建一个虚拟环境
    pycharm使用bootstrap组件方法
    linux安装配置python环境以及虚拟环境和django下载
    luffy项目搭建流程(Django前后端分离项目范本)
    python微信服务号关注授权、消息推送流程
    Celery—分布式的异步任务处理系统
  • 原文地址:https://www.cnblogs.com/8023spz/p/9471077.html
Copyright © 2011-2022 走看看