洛谷[P1482]Cantor表(升级版)

题目传送门OvO


题目描述

现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的:

1/1 1/2 1/3 1/4 1/5 …

2/1 2/2 2/3 2/4 …

3/1 3/2 3/3 …

4/1 4/2 …

5/1 …

… 这次与NOIp1999第一题不同的是:这次需输入两个分数(不一定是最简分数),算出这两个分数的积(注意该约分的要约分)后输出积在原表的第几列第几行(若积是整数或1/积,则以“积/1”或“1/积”结算)。

输入输出格式

输入格式:

共两行。每行输入一个分数(不一定是最简分数)。

输出格式:

两个整数,表示输入的两个分数的积在表中的第几列第几行,注意该约分的要约分。


先喷一下这题太水了,,,


首先,你要知道:
约分后的分母是行,分子是列。
于是问题来了:
怎么约分?
很简单:用辗转相除法求最大公约数,然后约分。
然后输出。
完事。

#include<bits/stdc++.h>//包含所有头文件的头文件
using namespace std;//为了用流,写它
int gcd(int a,int b){//辗转相除法求最大公约数
    if (!b)return a;//如果b==0,a是最大公约数
    else return gcd(b,a%b);//不然继续
}
int main(){
    ios::sync_with_stdio(false);//流优化
    int a,b,c,d,t;
    char hh;//这家伙对付‘/’号
    cin>>a>>hh>>b>>c>>hh>>d;//读入,不解释
    a*=c;b*=d;//乘一下
    t=gcd(a,b);//求最大公约数
    a/=t,b/=t;//约分
    cout<<b<<" "<<a;//输出
    return 0;//庄严地结束
}

传说中的80行代码:

#include<iostream>
#include<cstdio>
using namespace std;
enum mode{upper=0,lower=1};
class Fraction
{
    private:
        int fz;
        int fm;
    public:
        Fraction();
        Fraction(int Fz,int Fm);
        ~Fraction();
        int showfrac(mode mde);
        void get_gcd();
        Fraction operator*(Fraction frac1);
};

Fraction::Fraction()
{
    fz=1;
    fm=1;
}

Fraction::Fraction(int Fz,int Fm)
{
    if(Fm==0)
        cerr<<"Error : Divided By Zero .\n";
    else
    {
        fz=Fz;
        fm=Fm;
    }
}

Fraction::~Fraction()
{
}

int Fraction::showfrac(mode mde)
{
    if(mde==0)
        return this->fz;
    else
        return this->fm;
}

void Fraction::get_gcd()
{
    int cp1=fz,cp2=fm;
    while(cp1!=0 && cp2!=0)
    {
        if(cp1>cp2)
            cp1%=cp2;
        else
            cp2%=cp1;
    }
    int gcd=cp1+cp2;
    fz/=gcd;
    fm/=gcd;
}

Fraction Fraction::operator*(Fraction frac1)
{
    Fraction answer(fz*frac1.showfrac(upper),frac1.showfrac(lower)*fm);
    answer.get_gcd();
    return answer;
}

int main()
{
    int a,b;
    scanf("%d/%d",&a,&b);
    Fraction f1(a,b);
    scanf("%d/%d",&a,&b);
    Fraction f2(a,b);
    Fraction f_ans=f1*f2;
    cout<<f_ans.showfrac(lower)<<" "<<f_ans.showfrac(upper)<<endl;
    return 0;
}

Pascal还是来一个吧:

var
    a,b,c,d:longint;
    s:string[11];//分子分母共10位,分数线1位
function gcd(x,y:longint):longint;//也可以用递归的方式写
var
    r,t:longint;
begin
    if x<y then begin t:=x; x:=y; y:=t; end;//以免出现x<y,x mod y=0的情况
    r:=x mod y;
    while r<>0 do
    begin
        x:=y; y:=r;
        r:=x mod y;
    end;//辗转相除
    exit(y);
end;
begin
    readln(s);
    val(copy(s,1,pos('/',s)-1),a);
    val(copy(s,pos('/',s)+1,9),b);//处理
    readln(s);
    val(copy(s,1,pos('/',s)-1),c); a:=a*c;
    val(copy(s,pos('/',s)+1,9),d); b:=b*d;//同上
    writeln(b div gcd(a,b),' ',a div gcd(a,b));
end.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值