Cantor表(升级版)

题目描述

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

P1482 Cantor表(升级版)_算法

这次与 NOIp1999 第一题不同的是:这次需输入两个分数(不一定是最简分数),算出这两个分数的积(注意需要约分至最简分数),输出积在原表的第几列第几行(若积形如 P1482 Cantor表(升级版)_java_02(即结果为整数)或者 P1482 Cantor表(升级版)_算法_03,则看作表内的 P1482 Cantor表(升级版)_洛谷_04P1482 Cantor表(升级版)_算法_03 结算)。

输入格式

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

输出格式

两个整数,表示输入的两个分数的积在表中的第几列第几行。

样例 #1

样例输入 #1

4/5
5/4

样例输出 #1

1 1

提示

数据范围

对于全部数据,两个分数的分母和分子均小于 P1482 Cantor表(升级版)_java_06

思路解析

本题主要考虑到有以下3点:①如何把"/"去掉,拿到要进行操作的数。②对乘出来的结果约分。③根据约分后的结果,输出在表中的位置。

对于①,可以采用String输入,用split()将字符串以"/"切割成两部分(都不含"/")。代码如下:

String s1 = scanner.next();
String[] split1 = s1.split("/");
int z1 = Integer.parseInt(split1[0]);
int f1 = Integer.parseInt(split1[1]);

String s2 = scanner.next();
String[] split2 = s2.split("/");
int z2 = Integer.parseInt(split2[0]);
int f2 = Integer.parseInt(split2[1]);

对于②,找最大公约数进行约分。代码如下:

public static int fun(int z, int f) {
    int m = z < f ? z : f;
    for (int i = m; i >= 1; i--) {
        if (z % i == 0 && f % i == 0) {
            return i;
        }
    }
    return 1;
}

对于③,看表发现规律即可。

完整代码


import java.util.Scanner;

public class P1482 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s1 = scanner.next();
        String[] split1 = s1.split("/");
        int z1 = Integer.parseInt(split1[0]);
        int f1 = Integer.parseInt(split1[1]);
        String s2 = scanner.next();
        String[] split2 = s2.split("/");
        int z2 = Integer.parseInt(split2[0]);
        int f2 = Integer.parseInt(split2[1]);
        int z = z1 * z2;
        int f = f1 * f2;
        int fun = fun(z, f);
        System.out.println(f / fun + " " + z / fun);

    }

    public static int fun(int z, int f) {
        int m = z < f ? z : f;
        for (int i = m; i >= 1; i--) {
            if (z % i == 0 && f % i == 0) {
                return i;
            }
        }
        return 1;
    }
}