Dead Fraction POJ - 1930

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...).

例如:0.abc edf ,循环后三位,假设是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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
纠正这个代码的错误之处#include <iostream> #include <string> using namespace std; class Fraction { private: int numerator; // 分子 int denominator; // 分母 public: Fraction(int num, int den); // 构造函数 // 重载运算符 Fraction operator+(const Fraction &fra) const; Fraction operator-(const Fraction &fra) const; Fraction operator*(const Fraction &fra) const; Fraction operator/(const Fraction &fra) const; Fraction& operator=(const Fraction &fra); void print() const; // 打印结果 }; // 构造函数 Fraction::Fraction(int num, int den) { // 省略部分代码 } // 重载加法运算符 Fraction Fraction::operator+(const Fraction &fra) const { // 省略部分代码 } // 重载减法运算符 Fraction Fraction::operator-(const Fraction &fra) const { // 省略部分代码 } // 重载乘法运算符 Fraction Fraction::operator*(const Fraction &fra) const { // 省略部分代码 } // 重载除法运算符 Fraction Fraction::operator/(const Fraction &fra) const { // 省略部分代码 } // 重载赋值运算符 Fraction& Fraction::operator=(const Fraction &fra) { // 省略部分代码 } // 打印最简分数或带分数 void Fraction::print() const { // 省略部分代码 } int main() { int x_num, x_den, y_num, y_den; cout << "Input x: "; scanf("%d/%d", &x_num, &x_den); // 格式化输入 cout << "Input y: "; scanf("%d/%d", &y_num, &y_den); // 格式化输入 Fraction x(x_num, x_den); Fraction y(y_num, y_den); Fraction result; // 加法 result = x + y; cout << "x+y="; result.print(); // 减法 result = x - y; cout << "x-y="; result.print(); // 乘法 result = x * y; cout << "x*y="; result.print(); // 除法 result = x / y; cout << "x/y="; result.print(); return 0; }
最新发布
05-25
这段代码看起来没有什么明显的错误,但是有一些需要注意的地方: 1. 在类的定义中,构造函数应该放在 public 权限下,否则在 main() 函数中无法调用。 2. 使用 scanf() 函数进行输入时,需要包含头文件 <cstdio>。 3. 在 operator=() 函数中,应该返回一个引用类型的对象,即 Fraction&。 4. 在 main() 函数中,应该使用 cout 而不是 printf() 进行输出。 修改后的代码如下: ``` #include <iostream> #include <string> #include <cstdio> using namespace std; class Fraction { public: Fraction(int num, int den); // 构造函数 Fraction& operator=(const Fraction &fra); // 重载赋值运算符 Fraction operator+(const Fraction &fra) const; // 重载加法运算符 Fraction operator-(const Fraction &fra) const; // 重载减法运算符 Fraction operator*(const Fraction &fra) const; // 重载乘法运算符 Fraction operator/(const Fraction &fra) const; // 重载除法运算符 void print() const; // 打印结果 private: int numerator; // 分子 int denominator; // 分母 }; // 构造函数 Fraction::Fraction(int num, int den) { numerator = num; denominator = den; } // 重载赋值运算符 Fraction& Fraction::operator=(const Fraction &fra) { numerator = fra.numerator; denominator = fra.denominator; return *this; } // 重载加法运算符 Fraction Fraction::operator+(const Fraction &fra) const { int num = numerator * fra.denominator + denominator * fra.numerator; int den = denominator * fra.denominator; return Fraction(num, den); } // 重载减法运算符 Fraction Fraction::operator-(const Fraction &fra) const { int num = numerator * fra.denominator - denominator * fra.numerator; int den = denominator * fra.denominator; return Fraction(num, den); } // 重载乘法运算符 Fraction Fraction::operator*(const Fraction &fra) const { int num = numerator * fra.numerator; int den = denominator * fra.denominator; return Fraction(num, den); } // 重载除法运算符 Fraction Fraction::operator/(const Fraction &fra) const { int num = numerator * fra.denominator; int den = denominator * fra.numerator; return Fraction(num, den); } // 打印最简分数或带分数 void Fraction::print() const { int integer = numerator / denominator; int num = numerator % denominator; int den = denominator; int gcd = __gcd(num, den); num /= gcd; den /= gcd; if (integer != 0) { cout << integer << " "; } if (num != 0) { cout << num << "/" << den; } else { cout << 0; } cout << endl; } int main() { int x_num, x_den, y_num, y_den; cout << "Input x: "; scanf("%d/%d", &x_num, &x_den); // 格式化输入 cout << "Input y: "; scanf("%d/%d", &y_num, &y_den); // 格式化输入 Fraction x(x_num, x_den); Fraction y(y_num, y_den); Fraction result; // 加法 result = x + y; cout << "x+y="; result.print(); // 减法 result = x - y; cout << "x-y="; result.print(); // 乘法 result = x * y; cout << "x*y="; result.print(); // 除法 result = x / y; cout << "x/y="; result.print(); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值