Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Atcoderでのループ回数について(Python)

解決したいこと

閲覧いただきありがとうございます。
現在AtcoderにPythonで参加している者です。

AtcoderのB問題について質問です。
Atcoder_abc285_b
について質問がありますので、どなたか教えていただければ幸いです。

該当するソースコード

# 285 b pypy3使った
n = int(input())
s = str(input())
for i in range(n-1):
    count = 0
    for j in range(n-i-1):
        if s[j] != s[j+i+1]:
            count += 1
        else:
            break
    print(count)
    count = 0

自分で試したこと

こちらのコードで提出したところ、テストコードのうち二つがTLEとなってしまいました。
私の理解では、一般的に10の9乗くらいのループは回せると聞いており、今回書いたコードは5000*5000のループ以下になるはずです。(本当はもっとループ回数は少ないはずです)

どうやら、Pypy3で提出すると、Pythonよりも高速に処理をしてくれるらしく、全く同じコードでACが出ました。
しかし、これがなぜTLEとなったのか、せっかくだし解決したいということで、本質問を投稿しました。

みなさま、よろしくお願い致します。

0

3Answer

とりあえず、こちらのコードで通ることは確認できました。

n = int(input())
s = input()
for i in range(1,n):
    for j in range(n-i):
        if s[j] == s[j+i]:
            break
    else:
        j = n-i
    print(j)

ただ、かなり細かい最適化になります。こんなことに気を使うぐらいなら、PyPy3を使う方が精神衛生上よろしいのではないでしょうか。

  • countを別途用意するのではなくjを利用する。ループ内の足し算が1回減らせる。途中でbreakしない場合にずれるのでelse:で対応。
  • iの範囲を0~n-1ではなく1~nにする。ループ内の足し算が1回減らせる。

問題の上の「提出結果」タブから他の人の回答が見えるので、Python(3.8.2)でACになっている人を検索してみるのも一つの方法です。

2Like

Comments

  1. @kouta0505

    Questioner

    @actorbug 様コメントありがとうございます。
    他の方の回答も見ましたが、Pythonで提出されている方だと実行時間ギリギリのようで、もう少し早く書けないものかと思いました。
    やはりPypy3を使った方がよいのですね。
    ご丁寧に回答いただきありがとうございました!!!

$10^{9}$はC言語でも(ループ内の処理がごく単純でなければ)かなり厳しいと思います。
Pythonはインタプリタですかね? $10^{6}$は通りますか?
PyPy3とかのコンパイラを使うのが常套手段だと思います。
ちなみに、AtCoderはコンパイル時間は実行時間に含まないはずです。


この問題の実行時間制限は2秒ですね(3秒が多いが)。
TLEとなった2つのテストケースは、どちらもループ回数は12,019,420でした。Pythonだと$10^{7}$は2秒で無理ということですかね。

2Like

Comments

  1. @kouta0505

    Questioner

    @nak435 様、コメントありがとうございます。
    おそらくインタプリタを使っています。
    Pythonだと10**7は2秒では間に合わなそうとのことですね。
    頭に入れてこれから頑張ります。

Pypyはjitコンパイラのオーバーヘッドが時間を費やしているのでは?cpythonの時間は何秒でしょうか?

C言語はコンパイラ時間は含めないのですか?

尚、print(count)は応答時間を費やしています。

for i in range(n-1): cpythonで改善
for j in range(n-i-1): ここが課題

今、呑んでいるので、range(n-i-1):を
マルチスレッドで処理するか?再帰定義でしょうか?コードが思い付きません。

焼け石に水ですが末行のcount = 0は蛇足?

0Like

Comments

  1. print(count)は応答時間を費やしています。の改善です。

    time python script.py

    script.py
    for x in range(5000):
        for y in range(5000):
            pass
        print(x)
    

    time python script.py

    script.py
    ans = []
    for x in range(5000):
        for y in range(5000):
            pass
        ans.append(x)
    
    for z in ans:
        print(z)
    

    の方がちょっと早いです。1sec稼げるとよいのですが?

Your answer might help someone💌