トップページに戻る    次の競技プログラミングの問題へ    前の競技プログラミングの問題へ

天下一プログラマーコンテスト2017 C 4/N

■■■問題■■■

整数Nが与えられる。
4/N = 1/h + 1/n + 1/w を満たす正整数 h,n,w を求めよ。
条件を満たす解が複数ある場合、どれを出力しても良い。

■■■入力■■■

N

●Nに対して h,n,w <= 3500 となる解が存在することが保証される

■■■出力■■■

条件を満たす正整数 h,n,w の組を空白区切りで1つ出力せよ。
h n w


C#のソース

using System;
using System.Collections.Generic;

class Program
{
    static string InputPattern = "InputX";

    static List<string> GetInputList()
    {
        var WillReturn = new List<string>();

        if (InputPattern == "Input1") {
            WillReturn.Add("2");
            //1 2 2
            // 4/2 = 1/1 + 1/2+ 1/2 である
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("3485");
            //872 1012974 1539173474040
            //解として3500を超える整数を使っても良い
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("4664");
            //3498 3498 3498
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    static void Main()
    {
        List<string> InputList = GetInputList();
        long N = long.Parse(InputList[0]);

        for (long B = 1; B <= 3500; B++) {
            for (long C = B; C <= 3500; C++) {
                long wkBunsi = -N * B * C;
                long wkBunbo = -4 * B * C + N * C + N * B;

                if (wkBunbo == 0) continue;
                if (wkBunsi % wkBunbo != 0) continue;
                long wkA = wkBunsi / wkBunbo;
                if (wkA <= 0) continue;

                Console.WriteLine("{0} {1} {2}", wkA, B, C);
                return;
            }
        }
    }
}


解説

下記のように、Aについて方程式を解いて、
1以上3500以下の、BとCの組み合わせを全探索してます。
(BとCについて対称なので、B <= C としてます)

4/N = 1/A + 1/B + 1/C
4/N = (BC+AC+AB) / ABC
4ABC = NBC + A*(NC+NB)
-NBC = -4ABC + A*(NC+NB)
-NBC = A*(-4BC + NC + NB)
A = (-NBC) / (-4BC + NC + NB)