Python
 Computer >> コンピューター >  >> プログラミング >> Python

競技プログラミングに役立つPythonの高速入出力(I/O)方法まとめ

競技プログラミングでは、入力をいかに速く読み込めるかが勝敗を左右する重要なポイントになります。本記事では、Pythonにおけるさまざまな入出力(I/O)方法を、具体例とともにわかりやすく解説していきます。

例として、CodeforcesやSPOJなどのオンラインジャッジで「4つの整数 a, b, c, d を読み込み、その積を出力する」というシンプルな問題を考えてみましょう。実装方法は複数あるため、順番に見ていきます。

基本の入力方法

方法1:リスト内包表記を使う

a, b, c, d = [int(x) for x in input().split()]
print(a*b*c*d)

方法2:map関数を使う

a, b, c, d = map(int, input().split())
print(a*b*c*d)

どちらも簡潔に書ける定番の方法ですが、さらに高速化したい場合は sys.stdinsys.stdout を直接使うのがおすすめです。

sys.stdin / sys.stdout による高速化

from sys import stdin, stdout
a, b, c, d = [int(x) for x in stdin.readline().rstrip().split()]
stdout.write(str(a*b*c*d) + "\n")

stdin.readline()input() よりもオーバーヘッドが小さく、大量の入力を扱う際に大きな差が生まれます。

実践例:SPOJ「INTEST – Enormous Input Test」

次に、実際の競技プログラミングの問題を使って、入出力方法の違いを体感してみましょう。ここではSPOJの有名な問題「INTEST – Enormous Input Test」を取り上げます。

問題概要

  • 入力:最初の行に2つの正整数 n と k(n, k ≤ 107)が与えられます。続く n 行には、それぞれ109以下の正整数 ti が1つずつ含まれます。
  • 出力:ti のうち k で割り切れるものの個数を、1つの整数として出力してください。

入出力例

Input
7 3
1
51
966369
7
9
999996
11

Output
4

方法1:input()を使うシンプルな実装

最も基本的な書き方です。ただし、n が最大107に達するような大量入力では処理が非常に遅く、実行時間制限(TLE)に引っかかる可能性が高い点に注意しましょう。

def main():
    n, k = [int(c) for c in input().split()]
    cnt = 0
    for _ in range(n):
        t = int(input())
        if t % k == 0:
            cnt += 1
    print(cnt)

if __name__ == "__main__":
    main()

方法2:stdin / stdout を使う実装

stdin.readline()stdout.write() に置き換えるだけで、前述の方法より大幅に高速化できます。

from sys import stdin, stdout

def main():
    n, k = [int(c) for c in input().split()]
    cnt = 0
    for _ in range(n):
        t = int(stdin.readline())
        if t % k == 0:
            cnt += 1
    stdout.write(str(cnt))

if __name__ == "__main__":
    main()

方法3:入力を一括読み込みする実装

さらに速いのが、readlines() で入力全体を一度に読み込み、リストとして処理する方法です。readline() を繰り返し呼び出すオーバーヘッドがなくなるため、方法2よりも高速に動作します。

from sys import stdin, stdout

def main():
    n, k = stdin.readline().split()
    n = int(n)
    k = int(k)

    cnt = 0
    lines = stdin.readlines()
    for line in lines:
        if int(line) % k == 0:
            cnt += 1
    stdout.write(str(cnt))

if __name__ == "__main__":
    main()

まとめ

Pythonの標準的な input() は手軽ですが、大量データの処理には不向きです。sys.stdin.readline()readlines() による一括読み込み、stdout.write() による出力を活用すれば、実行時間を大幅に短縮できます。「TLE(Time Limit Exceeded)で悩んでいる」という方は、ぜひこれらの手法を試してみてください。

  1. 競技プログラミングでPythonが選ばれる理由とは?初心者にもわかる5つのメリット

    競技プログラミングとは、適切なデータ構造を選択し、効率的なアルゴリズムを実装することで課題を解決するコーディング活動のことです。プログラマーの思考力や実装力が多角的に試される場となっています。 競技では、出題された仮想的なプログラミング問題に対して、さまざまなロジックを駆使して解法を見つけ出す必要があります。さらに重要なのは、単に正解を出すだけでなく、時間計算量・空間計算量の両面で優れた「効率的な」解法を導くことです。 競技プログラミングの問題文の一例を挙げてみましょう。 【問題例】 長さnの文字列sが与えられます。sは小文字のラテン文字のみで構成されています。 部分文字列とは、元の文字列から

  2. PythonのTurtleグラフィックス入門!基本メソッド一覧と図形描画サンプルコード集

    Turtle(タートル)はPythonに標準搭載された特殊な機能で、専用の描画ウィンドウ上に簡単に図形を描くことができるモジュールです。 使い方はとてもシンプルです。まずturtleモジュールをインポートし、次にウィンドウ(Screen)を作成、その後タートルオブジェクトを生成します。あとは各種メソッドを呼び出すだけで、キャンバス上に自由に描画できます。この記事では、よく使われるメソッドの一覧表と、正方形・星・六角形などの具体的な描画例をサンプルコード付きで解説します。 主なTurtleメソッド一覧 メソッド パラメータ 説明 Turtle() なし 新しいタートルオブジェクトを作成