Dead Fraction POJ

来源:互联网 发布:win10网络重置后怎么办 编辑:程序博客网 时间:2024/04/29 02:51
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/91/51186531/2500000
Hint
Note that an exact decimal fraction has two repeating expansions (e.g. 1/5 = 0.2000... = 0.19999...).

例如:0.abcedf ,循环后三位,假设是n位,abc当做整数部分看作是m位,x*10^(m+n)之后变成 abcedf.edfedf..., 那如果我只是扩大整数倍的话,就是x*10^m   abc.edfedf..

两者一想减,x*10^(m+n)-x*10^m=整数(假设ans),那么x=ans/(10^(m+n)-10^n), 假设分子是s,分母是t的话,我们再去找到gcd(s,t),就是最简了。

题目中没有给出到底谁是循环节,所以我们需要从比最长少一位开始枚举。

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <string>#include <cmath>using namespace std;const int INF=0x3f3f3f3f;typedef long long ll;/*pow函数以后我们也要少用,尽量自己写出来,除非是小数的情况只要指数是整数的话,我们就自己写,现在不敢再去乱放参数了,orz跪了pow(10,2)不一定是100,所以我们还是自己写吧*/int gcd(int n,int m)//求最大公约数,这个函数也是蛮吊的{    if(m==0)        return n; //n%m==0(n与m的余数为0)    return gcd(m,n%m);//(n是大数,m是小数)}ll pow_self(int a,int b)//以后的pow_self()函数{    ll val=1;    while(b--)    {        val*=a;    }    return val;}int main(){    int all,num,l,a,b,k,mis,mns;    char str[100];    while(gets(str)&&strcmp(str,"0"))    {        l=0;all=0;mis=INF;        for(int i=2;str[i]!='.';i++)        {            all=all*10+str[i]-48;            l++;        }        num=all;        for(int j=1;j<=l;j++)        {            num=num/10;            a=all-num;            int n=l-j;            int m=j;            b=pow_self(10,l)-pow_self(10,l-j);//总的位数,减掉整数的位数            k=gcd(b,a);            if(b/k<mis)            {                mns=a/k;                mis=b/k;            }        }        printf("%d/%d\n",mns,mis);    }    return 0;}