山傘のプログラミング勉強日記

プログラミングに関する日記とどうでもよい雑記からなるブログです。

[yukicoder] No.141 魔法少女コバ

問題

No.141 魔法少女コバ - yukicoder

真分数と仮分数で行うべき操作が変わります。

最大公約数を求めて約分をするために、ユークリッドの互除法を使いました。

考え方

真分数とは、分母が分子より大きい分数であり、仮分数とは分母が分子以下の分数を意味します。

真分数は、仮分数の逆数を取ることでしかこの操作によって作ることはできません。

また、逆数の操作を始めて行って得られる分数は、分子が 1の分数となります。

これらのことに注意します。

例えば、 \dfrac{2}{3}

 \dfrac{2}{3} = \left ( \dfrac{3}{2} \right ) ^{-1}

 \dfrac{3}{2} = 1 + \dfrac{1}{2}

のように分解されます。ここで、

 \dfrac{1}{2} は、二回の操作で得られるので、求める答えは 2 + 1 + 1 = 4

となります。

また、 \dfrac{10}{7}

 \dfrac{10}{7} = 1 + \dfrac{3}{7}

 \dfrac{7}{3} = 2 + \dfrac{1}{3}

のように分解できるので、

求める答えは、 3 + 2 + 1 + 1 = 7

となります。

コード

import java.util.Scanner;

public class Exec0141 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        int M = scan.nextInt();
        int min = Math.min(N, M);
        int max = Math.max(N, M);
        scan.close();
        if(N == M) {
            System.out.println(0);
            System.exit(0);
        }
        // m <= n
        // ユークリッドの互除法
        int n = max;
        int m = min;
        int r = -1;
        while (r != 0) {
            r = n % m;
            n = m;
            m = r;
        }
        int a = N / n;
        int b = M / n;
        // M / N = a / b
        int cnt = 0;
        int d1, n1;
        if(a > b) {
            d1 = b;
            n1 = a;
        }else {
            d1 = a;
            n1 = b;
            cnt ++;
        }

        if(d1 == 1) {
            cnt += n1 - 1;
            System.out.println(cnt);
            System.exit(0);
        }

        int d2, n2;
        int cnt1 = 0;
        while(n1 != 1) {
            int t = n1 / d1;
            cnt1 ++;
            cnt += t;
            //System.out.println("t " + t + " cnt " + cnt);
            //System.out.println(n1 + " " + d1);
            d2 = n1 % d1;
            n2 = d1;
            n1 = n2;
            d1 = d2;
            if(d1 == 1) {
                cnt += n1;
                break;
            }
        }
        System.out.println(cnt + cnt1 - 1);
    }
}