1 条题解

  • 0
    @ 2025-8-24 21:26:37

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar ggylz49
    吾爱大风与烈酒,亦爱孤独与自由。

    搬运于2025-08-24 21:26:36,当前版本为作者最后更新于2024-03-03 13:41:18,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题外话

    在进入正题之前,先介绍一下 c++ 一些好用的东西(STL 是 c++ 的宝库!)。

    • __gcd(int a,int b):计算 gcd(a,b)\gcd(a,b),也就是 a,ba,b 的最大公约数。
    • 如果定义一个结构体(这里就不在详解结构体了),那么结构体变量(不是成员变量)都可以作为函数的输入值或返回值。例如定义一个结构体 lt
    struct lt
    {
    	int a,b;
    };
    

    那么如下的函数可行:

    lt find(lt x)
    {
    	x.a=x.a+x.b;
    	return x;
    }
    

    这两个东西会在本题中用到。

    详解

    首先定义一个结构体,表示分数。

    struct fs
    {
        long long fm,fz;//开long long最保险了!
    };//结构体定义后要加分号
    

    然后就是一些杂七杂八的函数了。

    1. fs yf(fs a) 对分数 aa 进行约分。返回一个分数。
    fs yf(fs a)
    {
        long long m=__gcd(a.fm,a.fz);//求出最大公约数
        a.fm/=m;
        a.fz/=m;//分别除掉
        return a;//返回约分后的分数
    }
    
    1. jia(fs a,fs b) 计算分数 a+ba+b,返回值也是分数。
    fs jia(fs x,fs y)
    {
        long long z=x.fm*y.fm;//直接将分母统一(虽然不是最小公倍数)
        x.fz*=y.fm;
        y.fz*=x.fm;//互相乘得到在分母为z的情况下的分子
        x.fm=z;
        y.fm=z;//统一分母
        fs answer;//答案
        answer.fz=x.fz+y.fz;//分子相加
        answer.fm=x.fm;//分母就按原来的咯
        return yf(answer);//记得约分
    }
    

    例如  2  4 + 3  4 \frac{\ 2 \ }{\ 4 \ }+\frac{\ 3 \ }{\ 4 \ },程序理解成  8  16 + 12  16 \frac{\ 8 \ }{\ 16 \ }+\frac{\ 12 \ }{\ 16 \ },约分后得到  5  4 \frac{\ 5 \ }{\ 4 \ }

    1. jian(fs a,fs b) 计算分数 aba-b,返回值也是分数。
    fs jian(fs x,fs y)
    {
        long long z=x.fm*y.fm;
        x.fz*=y.fm;
        y.fz*=x.fm;
        x.fm=z;
        y.fm=z;
        fs answer;
        answer.fz=x.fz-y.fz;
        answer.fm=x.fm;
        return yf(answer);//就不解释了,可按照加法自行理解
    }
    
    1. 主函数。
    int main()
    {
        fs a,b;
        char ysf;
        scanf("%lld/%lld",&a.fz,&a.fm);//输入第一个分数,后面就按 [运算符 分数] 格式读入
        cin>>ysf;//输入运算符
        while (scanf("%lld/%lld",&b.fz,&b.fm)!=EOF)//保证读入不为空
        {
            if (ysf==EOF)break;//如果输入的运算符本身为空,跳出
            else if (ysf=='+'){a=jia(a,b);}//把a赋值成a+b结果,之后输入b再运算
            else if (ysf=='-'){a=jian(a,b);}//a-b,同上
            cin>>ysf;//最后输入下一个运算符
        }
        if (a.fm<0&&a.fz>0)//如果分母乘着乘着就变成了负数
        {
            a.fm=abs(a.fm);
            a.fz-=a.fz*2;//分子变负,分母变正
        }
        if (a.fm==1)cout<<a.fz;//特判分母为1,直接输出分子
        else cout<<a.fz<<'/'<<a.fm;//不然照常输出
        return 0;
    }
    

    不过只能得 Unaccped 100\text{Unaccped} \ 100 分。因为第一次输入没有约分,所以如果只有 11 个分数,就会输出原来的分数,就不是约分过的了。所以输入时就先约分一次,如下所示。

    code

    #include <bits/stdc++.h>//万能头文件
    using namespace std;
    struct fs
    {
        long long fm,fz;
    };
    fs yf(fs a)
    {
        long long m=__gcd(a.fm,a.fz);
        a.fm/=m;
        a.fz/=m;
        return a;
    }
    fs jia(fs x,fs y)
    {
        long long z=x.fm*y.fm;
        x.fz*=y.fm;
        y.fz*=x.fm;
        x.fm=z;
        y.fm=z;
        fs answer;
        answer.fz=x.fz+y.fz;
        answer.fm=x.fm;
        return yf(answer);
    }
    fs jian(fs x,fs y)
    {
        long long z=x.fm*y.fm;
        x.fz*=y.fm;
        y.fz*=x.fm;
        x.fm=z;
        y.fm=z;
        fs answer;
        answer.fz=x.fz-y.fz;
        answer.fm=x.fm;
        return yf(answer);//约分是个好习惯
    }
    int main()
    {
        fs a,b;
        char ysf;
        scanf("%lld/%lld",&a.fz,&a.fm);
        a=yf(a);
        cin>>ysf;
        while (scanf("%lld/%lld",&b.fz,&b.fm)!=EOF)
        {
            if (ysf==EOF)break;
            else if (ysf=='+'){a=jia(a,b);}
            else if (ysf=='-'){a=jian(a,b);}
            cin>>ysf;
        }
        if (a.fm<0&&a.fz>0)
        {
            a.fm=abs(a.fm);
            a.fz-=a.fz*2;
        }
        if (a.fm==1)cout<<a.fz;
        else cout<<a.fz<<'/'<<a.fm;
        return 0;
    }
    

    约法三章

    1. 这个是最长的题解,不要毁谤,谢谢。
    2. 题解写了一天半,你若喜欢请点赞。若你抄袭不点赞,被举报有你好看。
    3. 有问题欢迎指正。如果有 hack 数据,我会尽快改正!
    • 1

    信息

    ID
    565
    时间
    1000ms
    内存
    512MiB
    难度
    2
    标签
    递交数
    0
    已通过
    0
    上传者