AtCoderのPAST    次のPASTの問題へ    前のPASTの問題へ

第15回PAST H 和で表現


問題へのリンク


C#のソース

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static string InputPattern = "InputX";

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

        if (InputPattern == "Input1") {
            WillReturn.Add("7");
            //3
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("1");
            //1
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("164312478120341038");
            //573258192
        }
        else if (InputPattern == "Input4") {
            WillReturn.Add("1000000000000000000");
        }
        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]);

        long L = 1;
        long R = N;

        while (L + 1 < R) {
            long Mid = (L + R) / 2;
            long CurrSankakusuu = DeriveSankakusuu(Mid);

            if (CurrSankakusuu <= N) {
                L = Mid;
            }
            else {
                R = Mid;
            }
        }
        Console.WriteLine(L);
    }

    // Iを引数として、I番目の三角数を返す
    static long DeriveSankakusuu(long pI)
    {
        long Val1 = pI;
        long Val2 = pI + 1;

        if (Val1 % 2 == 0) Val1 /= 2;
        if (Val2 % 2 == 0) Val2 /= 2;

        if (WillOverProd(Val1, Val2, long.MaxValue)) {
            return long.MaxValue;
        }
        return Val1 * Val2;
    }

    // 2正数の掛け算が、Limitを超えるかを返す
    static bool WillOverProd(long pA, long pB, long pLimit)
    {
        return pA > pLimit / pB;
    }
}


解説

Nが三角数だと仮定します。
 1の場合の解は1
 3の場合の解は2
 6の場合の解は3
10の場合の解は4
15の場合の解は5
21の場合の解は6
と分かります。

Nが三角数でない場合は、単調性により、最大下界の三角数の時が解になります。
なので、二分探索で最大下界を求めれば良いです。