AtCoder解答用テンプレートこうしてます
閉じる
閉じる

新しい記事を投稿しました。シェアして読者に伝えましょう

×

AtCoder解答用テンプレートこうしてます

2018-07-29 21:51
    def c_modulo_summation(N, A):
        return sum(a-1 for a in A)

    import os
    import sys
    import io
    import pathlib
    import textwrap

    if os.name == 'nt':
        sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')
        sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
        sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
    os.chdir(pathlib.Path(__file__).parent.resolve())

    for SAMPLE_CASE_NUM, INPUT in enumerate([
        """
        3
        3 4 6
        """,
        """
        5
        7 46 11 20 11
        """,
        """
        7
        994 518 941 851 647 2 581
        """
    ], 1):
        sys.stdin = io.StringIO(textwrap.dedent(INPUT).strip())
        N = int(input())
        A = [int(i) for i in input().split()]
        print(f'C-{SAMPLE_CASE_NUM}:{c_modulo_summation(N, A)}')

    上のコード (Python3.6以降で動作する) は、"AtCoder Beginner Contest 103" のC問題のサンプルケースに対する解を求めるためのものです。以下の点が特徴です。

    1. 解答を関数の中に書いている
    2. 関数の外で入力を受け付けている
    3. 入力を別ファイルに書いておかず、解答と同一ファイルに書いている

    こうしている理由は、個人的に次のような感覚を持っているからです。

    1. 「解が複数あるときはそのうち1つを出力すればよい」場合、解が1つ見つかればそれを即座に返り値にすればいい(解を出力してsys.exit()でもいいけど)
    2. 関数に渡す前に値のチェックをしておきたい(AtCoderでは見かけないので書いてはいないけれど、形式が違う入力や悪意のある入力を弾く必要があるため)
    3. サンプルの内容を確認するためにいちいち他のファイルを開きたくない

    このコードでは、日本語の入力があったときや日本語で出力を行うことを考えて標準入出力の文字コードをUTF-8にしたり、ファイルに書き込むことを考えてディレクトリを設定していたりしますが(if os.name == 'nt': のあたりの部分)、競技プログラミングで日本語の入力が与えられたり途中でファイルに書き込む必要があったりすることは今のところなかったので、不要だとは思います。

    2018/08/01 追記

    Windows 10 UTF-8利用機能が追加されていたようです
    ↑こちらのサイトのように、ワールドワイド言語サポートで Unicode UTF-8 を使用すると、ソースコード側で標準入出力のエンコーディングを設定しなくても日本語が文字化けすることがなくなりました。というわけで、 sys.std* = ... の部分は現在消してあります。

    2018/10/01 追記

    テンプレートをさらに変えました。内容は以下の通り。

    1. デコレータを使うようにした(入力を受け取って解を表示する部分も、コピペして提出欄にそのまま貼り付けれれるようになった。参考:Pythonのデコレータについて)
    2. import文の並びを変えた(VSCodeの "import 文を並び替える" の結果に従うようにした)
    def output_format(q):
        def decoration(func):
            def wrapper(*args, **kwargs):
                import time
                start = time.perf_counter()
                ans = func(*args, **kwargs)
                elapse = round((time.perf_counter() - start) * 1000, 3)
                res = f'{q}-{SAMPLE_CASE_NUM}: {ans} ({elapse}ms)'
                return res
            return wrapper
        return decoration


    @output_format('C')
    def c_modulo_summation(N, A):
        return sum(a - 1 for a in A)


    if __name__ == '__main__':
        import io
        import os
        import pathlib
        import sys
        import textwrap
        os.chdir(pathlib.Path(__file__).parent.resolve())

        for SAMPLE_CASE_NUM, INPUT in enumerate([
            """
            3
            3 4 6
            """,
            """
            5
            7 46 11 20 11
            """,
            """
            7
            994 518 941 851 647 2 581
            """
        ], 1):
            sys.stdin = io.StringIO(textwrap.dedent(INPUT).strip())
            N = int(input())
            A = [int(i) for i in input().split()]
            print(c_modulo_summation(N, A))
    広告
    コメントを書く
    コメントをするには、
    ログインして下さい。