問題を読み、コードを書き、入力例で確認し、全部OKだった。
意気揚々と提出したら 非道の「RE」「MLE」 。
どうしたらいいの・・・。
そんな時の対処法をお伝えします。
なお、この記事は初心者~灰色の方向けに書いていますので、茶色以上の人には当たり前に感じることが多いと思います。
また、難易度が高めの問題で起こりがちなRE,MLEも書きません。
茶色以上の人は勝手に頑張ってくれ。
RE
REとは
実行時エラー(Runtime Error)の略です。
実行時に何らかのエラーが吐かれたらこれになります。
原因と対処
競技プログラミングでサンプルは通っているのにREになる原因は主に二つです。
・配列外参照
「IndexError: list index out of range」(リスト インデックスが範囲外)
REは9割これ。
リストの長さを超えた場所を参照しようとしていますという意味です。
例えば以下のコード。
A=[1,2,3]
x=A[3]
Aの長さは3ですがA[3]を参照しようとしています。
pythonでは先頭をA[0]、次をA[1]、と数えるので長さ3のリストの末尾はA[2]になるわけです。
しかしA[3]という存在しない場所を見ようとしているからエラーになります。
対処法としてはどのような入力のときにこれが起こっているかを確認するということになります。
エラーが出るまで入力をてきとうに作りまくってみましょう。
特に制約の端っこ、例えば1≤N≤10^5であればN=1のケースでエラーになることが多いです。
・0除算
「ZeroDivisionError: division by zero」(0で割っている)
残り1割がこれ。
例えば以下のコード
print(1/0)
「1/0を出力しろ」ということなのですが当然0で割れないのでエラーになります。
「制約1≤Ai≤10^5だと思ってたけどよくよく見たら0≤Ai≤10^5だったわ」みたいなパターンで起こります。
問題と制約はしっかり確認しましょう。
MLE
MLEとは
メモリ制限超過(Memory Limit Exceeded)の略です。
問題ページの左上にちっちゃーく「メモリ制限: 1024 MB」と書いていますね。
これ以上メモリ使ってるよって意味です。
原因と対処
・リストでかすぎ
10割これ。
長さが10^9以上あるリストを作った場合など、大きすぎるリストを作るとMLEします。
例えばこんなコードです。
A=[0]*(10**9)
これくらいわかりやすいとすぐ見つかるんですが、他には
・二次元配列が10^5*10^5
・長さが(Aの最大値)のリストを作ろうとしているが制約が1≤Ai≤10^9
などのパターンもあります。
対処法は
・まず大きなリストを作らずとも解けないか考える
・それが無理ならリストではなく連想配列(dict)でなんとかできないか考える
(リストのA[999999999]は参照できないけど連想配列のキーを「999999999」にした値は取り出せるみたいな使い方です。)
とは言ってもMLEは稀にしか起きない問題です。
問題をたくさん解いていれば自然とMLEの対処法もわかってくるので、まだ起きたことがない人はあまり気にせず精進に励みましょう。
テストケースは公開されています。
どのケースでREするのか、MLEするのかわからない、という場合。
コンテストが終わった後であればテストケースの入力、出力を確認する事ができます。
コンテスト後だいたい1週間から2週間程度で公開されるようです。
これでRE、MLEになるケースを直接確認できます。
正解を確認するのも大切ですが、 なぜ間違っているのか を確認するのも同じくらい大切です。
皆様も良い競プロライフを!