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

No.164 ちっちゃくないよ!!

■■■問題■■■

入力に N 個の1以上の整数が与えられる。
そのうち、最小の値を出力せよ。

ただし、入力は10進法表記とは限らず、
与えられる整数1つにつき、それぞれ2進法表記から36進法表記までの間のいずれかで与えられ、
正当に解釈できる限り何進法表記として解釈しても構わないが、
入力が意図する値は、解釈できるうちの最小の数値である。

通常16進法表記は、各桁に [ 0〜9, A〜F ] の16文字を使用するが、
本問題ではこれを拡張して17進法表記以降は G〜Z を順に追加で使用し、
36進法表記では [ 0〜9, A〜Z ] の36文字を使用することとする。

例として、「YUKICODER」を36進法表記で表した数値としたとき、
10進法表記では、98313307106787 となる。
また、与えられる整数は0で始まる場合もあることに注意せよ。

■■■入力■■■

N
V1
V2
・・・
VN

1行目に入力の個数を表す整数 N (1 <= N <= 1000) が与えられる。
続くN行に、整数 Vi (1 <= i <= N) が与えられる。
整数 Vi は、2進法表記から36進法表記までの間のいずれかで表現された1以上の整数で、
数字(0〜9)またはアルファベット大文字(A〜Z)で構成される 12 文字以内の文字列である。

■■■出力■■■

与えられた整数のうち、最小の値を10進法表記で出力せよ。
ただし、出力は0で始まってはならない。


C#のソース

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

class Program
{
    static string InputPattern = "Input1";

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

        if (InputPattern == "Input1") {
            WillReturn.Add("4");
            WillReturn.Add("41");
            WillReturn.Add("32");
            WillReturn.Add("23");
            WillReturn.Add("14");
            //9
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("9");
            WillReturn.Add("000223444444");
            WillReturn.Add("00003641077");
            WillReturn.Add("0001783660");
            WillReturn.Add("00002DOOO");
            WillReturn.Add("00052KC0");
            WillReturn.Add("0064JJJ");
            WillReturn.Add("0BG938");
            WillReturn.Add("F423F");
            WillReturn.Add("UGHV");
            //999999
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("7");
            WillReturn.Add("YUKICODER");
            WillReturn.Add("TOPCODER");
            WillReturn.Add("ATCODER");
            WillReturn.Add("CODEFORCES");
            WillReturn.Add("CODECHEF");
            WillReturn.Add("AIZUONLINE");
            WillReturn.Add("HACKERRANK");
            //8005080147
        }
        else if (InputPattern == "Input4") {
            WillReturn.Add("1");
            WillReturn.Add("0XFFFFFFFFFF");
            //69062819408545233
            //先頭が0Xだからといって16進数であるわけではありません。 
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    static void Main()
    {
        List<string> InputList = GetInputList();
        string[] VArr = InputList.Skip(1).ToArray();

        //foreach (string EachStr in VArr) {
        //    Console.WriteLine(DeriveVal(EachStr));
        //}

        Console.WriteLine(VArr.Min(X => DeriveVal(X)));
    }

    //解釈できるうちで最小の数を、Decimal型で返す
    static decimal DeriveVal(string pTarget)
    {
        int ShinSuu = DeriveShinSuu(pTarget);
        Console.WriteLine("{0}は{1}進数", pTarget, ShinSuu);

        decimal WillReturn = 0;

        for (int I = 0; I <= pTarget.Length - 1; I++) {
            char CurrChar = pTarget[pTarget.Length - 1 - I];
            int CurrInt;
            if (CurrChar <= '9') CurrInt = CurrChar - '0';
            else CurrInt = CurrChar - 'A' + 10;

            WillReturn += DeriveBekijyou(CurrInt, ShinSuu, I);
        }
        return WillReturn;
    }

    //何進数かを求める
    static int DeriveShinSuu(string pTarget)
    {
        //最大の文字
        char MaxChar = pTarget.Max();

        if (MaxChar <= '9')
            return MaxChar - '0' + 1;
        return MaxChar - 'A' + 10 + 1;
    }

    //X*(AのN乗)をDecimal型で返す
    static decimal DeriveBekijyou(int pX, int pA, int pN)
    {
        decimal WillReturn = pX;

        for (int I = 1; I <= pN; I++) {
            WillReturn *= pA;
        }
        return WillReturn;
    }
}


デバッグ情報付の実行結果

41は5進数
32は4進数
23は4進数
14は5進数
9


解説

最大値は、ZZZZZZZZZZZZで、36の12乗ですが
12*Log10(36) > 12*Log10(100) = 24
なので、Decimal型で充分な範囲となります。

(Decimal型の有効桁は28桁)