質問するログイン新規登録
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

3回答

778閲覧

Atcoder 競技プログラミングの鉄則 演習問題集 第5問のREになってしまう理由がわからないです。

TMYchan

総合スコア0

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2025/09/16 03:28

0

1

実現したいこと

ソートコードの原因解説と私のコードをどのように修正すればよろしいでしょうか?

発生している問題・分からないこと

私のコードでコンパイル提出するとREになってしまいます。

該当のソースコード

python

1N,K = map(int, input().split()) 2count = 0 3 4for i in range(1, N+1): 5 for j in range(1, N+1): 6 for z in range(1, N+1): 7 if i+j+z == K: 8 count += 1 9 10print(count)

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

特に変更したりAIは使ってません。

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

melian

2025/09/16 05:48

入力例2の場合、ループ回数は 3000**3 = 27,000,000,000 回(270億回)になります。手元のPC(Intel Core i5-8500T (6)/3.50 GHz)で実行すると10分経過しても終了しません。つまり、制限時間オーバーになっていると考えられます。なので、修正方法としては総当り(brute force)ではなく適切なアルゴリズムを採用することになります。
TakaiY

2025/09/16 05:55

僕も時間がかかることが問題かと思ったのですが、その場合REでなくTLEになるんじゃないかと思って黙ってましたがどうなんでしょう。
melian

2025/09/16 07:09

三重ループを二重ループにするとループ回数は900万回になります。先程の環境では1.77秒で完了なので間に合うかもしれません。もっと効率的な方法があるかと思いますが、参考にしてみてください。 https://www.mycompiler.io/view/598zz3iL7CF
bsdfan

2025/09/16 08:49

時間がかかりすぎているのならREではなくTLEになると思います。 ひとつ前の質問でも、正常に動作する回答のものでREになったりしているようなので、コピペでのミスとか、その辺も注意してみたほうがいいように思います。 pythonの場合、インデントでのエラーもREになると思います。
meg_

2025/09/16 10:40

> Atcoder 競技プログラミングの鉄則 演習問題集 第5問のREになってしまう理由がわからないです。 URLは追記できますか? > 特に変更したりAIは使ってません。 何の話ですか?「試したこと・調べたこと」を記入する欄なのでプログラムの補足情報は本文に書く情報かと思います。
actorbug

2025/09/16 12:53

REになると言っているのは、こちらの提出結果のことでしょうか。 https://atcoder.jp/contests/tessoku-book/submissions/69378422 こちらですが、Atcoder 競技プログラミングの鉄則 演習問題集 第5問ではなく、第1問に対して回答しています。 第5問に回答したいのであれば、こちらのページにソースコードを入力してください。 https://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_e
kikukiku

2025/09/16 23:34

>こんな感じにすると計算量が更に半分にできそう。 >https://www.mycompiler.io/view/E4Nl6x3p9Vz 上記では計算量を半分にできないことが判明しました。 すみません。取り下げます。
TMYchan

2025/09/17 03:17 編集

@actorbugさん 解答ありがとうございます。以下のリンクで再度提出しましたら、結果がTLEになりました。 しかし、上のコードだとなぜ時間がかかりすぎてしまうのですがなぜでしょうか。
TakaiY

2025/09/17 04:22

> 結果がTLEになりました。 > しかし、上のコードだとなぜ時間がかかりすぎてしまうのですがなぜでしょうか。 この問題って、「1 章:アルゴリズムと計算量」の題名にもありますが、パッと思いつく方法だと計算量が多くて時間がかかりすぎてしまう問題を、適切なアルゴリズムを1つまたは複数適用することで制限時間内に解けるようになること、が目的の演習問題です。 なので、アルゴリズムや計算量の見積り方などを勉強してこの問題が解けるようになりましょう。って感じですね。
kikukiku

2025/09/17 06:56

TMYchanさんのアルゴリズムは、 Nの3重ループになっているので、 最大3000×3000×3000=270億回ループすることになります。 アルゴリズムを工夫することで Nの2重ループにすることができます。 3000×3000=900万回 上記にようにすれば、3000倍処理速度を上げることができるということですね。 2重ループへの仕方は、すでに他の方が回答している通りです。
TMYchan

2025/09/18 03:12

TakaiYさん、kikukikuさん 返答ありがとうございます。ループ回数が多すぎて制約を超えてしまうことだと理解しました。ループの方をもう少し考えてみます。
guest

回答3

0

質問へのコメントにも書かれていますが,提示されたコードでは実行時間の条件を満たせないと思われますので,少し視点を変えた方法を示します。

1枚目のカードが i1N)の場合,残り(j = K - i)に着目すると以下のことが言えます。

  • j が2枚目と3枚目のカードの和の範囲(2N + N)外の場合は条件を満たさないのでカウントは不要

  • jN + 1 以下の場合は,2枚目も3枚目も 1 以上が条件なので2枚目と3枚目の和が j に一致する場合の数は j - 1 通り

  • jN + 1 を超える場合は,3枚目が N 以下なので2枚目は j - N 以上の必要があり,求める場合の数は N - (j - N - 1) 通り

これらを基にした記述例を下記に示します。

また,AtCoder への 提出結果 も参照ください。

Python

1N, K = map(int, input().split()) 2count = 0 3 4for i in range(1, N + 1): 5 j = K - i 6 if j < 2: 7 continue 8 elif j <= N + 1: 9 count += j - 1 10 elif j <= N + N: 11 count += N + N - j + 1 12 13print(count)

投稿2025/09/17 04:11

編集2025/09/17 06:17
little_street

総合スコア533

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kikukiku

2025/09/17 07:46

実行時間制限が2秒なんですね。 ちゃんと問題文を読んでいなかったです。 2秒なら1重ループにおさめておかないと無理ですね。 すばらしい。
TMYchan

2025/09/18 03:25

little_streetさん 返信ありがとうございます。 上記の解説で不明点がありましたので質問失礼いたします。 iからjに行くときに範囲が1以上から2に変わったのはなぜでしょうか?
kikukiku

2025/09/18 04:22

>j が2枚目と3枚目のカードの和の範囲(2 〜 N + N)外の場合は条件を満たさないのでカウントは不要 上記の部分のことですね。 2枚目の取りうる範囲が、1~N、 3枚目の取りうる範囲が、1~Nですので jは2枚目と3枚目の和なので、2~2Nになります。
guest

0

python

1N,K = map(int, input().split()) 2count = 0 3 4for i in range(1, N+1): 5 for j in range(1, N+1): 6 z = K - i -j 7 if z >= 1 and z <= N: 8 count += 1 9 10print(count)

解答に答えてくれた皆様私のほうであらたに改変をいたしたところACをとることができました。ループを三回にしないでもやる方法を編み出したので共有いたします。上記の点で悪いところがまだありましたらお伺いしてもいいでしょうか?

投稿2025/09/18 03:41

TMYchan

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kikukiku

2025/09/18 04:29

2重ループでもAC取れるのですね。 なら、この方法が一番アルゴリズムとしてわかりやすいと思います。 もっと処理速度は上げる方法もあるようで、 別の方が回答して頂いています。 ※1重ループの方法 ※0重ループの方法(階乗計算があるので0重と言えるかどうかは別問題))。
melian

2025/09/18 05:00 編集

(私から言うのも何ですが)提示されているコードは、私が9月16日の16時9分に本質問にコメントした内容と同じです。 > 三重ループを二重ループにするとループ回数は900万回になります。先程の環境では1.77秒で完了なので間に合うかもしれません。もっと効率的な方法があるかと思いますが、参考にしてみてください。 > https://www.mycompiler.io/view/598zz3iL7CF 質問にあるコードの計算量は O(N**3) で、こちらのコードでは O(N**2) になります。little_street さんの回答は O(N) になるので、処理速度を優先するのであれば O(N) の方が有利です。(実際に100倍以上高速です) 私の回答は O(1) ですが、実質的には O(N) と同等です。(comb(n, 2) を n*(n-1)//2 に置き換れば、もう少し速くなるかもしれません)
fana

2025/09/18 05:32

(オーダー表記で物事を考えるなら全く意味ない話ですが) 簡便に2重ループでやるという方向だとして,ループの範囲: > range(1, N+1) の部分を少しだけは考えるかな? とか思いました. 例えば「 K-i の値が 3 しかないような場合に, j のループを 1000 回とか回すのは明らかに無駄だよな…」とか. とはいえそこで考えすぎる(?)と,既存回答の1重ループな話に行きついてしまいそうですが…… アルゴリズムが変わらない範囲(:「簡便に」の範囲)内でさくっとやれることだけはやる的な?
kikukiku

2025/09/18 06:03

melianさん >私が9月16日の16時9分に本質問にコメントした内容と同じです。 まったくその通り。 fanaさん >> range(1, N+1) >の部分を少しだけは考えるかな? とか思いました. 2つ目のループ中で、条件に合致したらbreakするということですよね。 それもありだと思います。 ※実はコメントしていませんが、自身で検証して動作しています。 今回はACを満足するということが命題なので、そこまでしなくてもという感じですね。
fana

2025/09/18 07:49

breakで抜けるのでも,ループ範囲の側を何か適切に決定するのでも良いですが,まぁそういう話です. 1つ目のループに関しても同様です(例えば K < N みたいな場合とか). (ぱっと見でなんか思ったことを書いちゃいましたが 計算量のオーダーが変わらないような変更はそもそも意味をなさない場面なので,無用な話でした.)
kikukiku

2025/09/18 08:33

>1つ目のループに関しても同様です(例えば K < N みたいな場合とか) なるほど、確かにそうですね。 この条件は考えてなかった。
guest

0

問題としては、以下の不定方程式を満たす3個の自然数(A, B, C)の組み合わせの個数を求めることになります。

A + B + C = K

制約は 1 <= A, B, C <= N です。

最初に A, B, C >= 1 の制約だけがある場合について考えます。これは Stars and Bars Algorithms を利用して解くことができます。

Stars and Bars Algorithms for Competitive Programming - GeeksforGeeks

  1. Distribution among groups where groups can have 0 objects:

Imagine you have N identical objects (which we represent as stars) that you want to distribute into K distinct groups, such that each group can have 0 to N number of elements. The Stars and Bars theorem states that there are C(N+K-1, K-1) ways to do this, where C denotes the binomial coefficient.

元の不定方程式を以下の様に置き換えます。

A = a + 1 B = b + 1 C = c + 1 # a, b, c >= 0 (a + 1) + (b + 1) + (c + 1) = K a + b + c = K - 3

この方程式(a + b + c = K - 3)を満たす a, b, c の組み合わせの個数は K - 3 個の star(星)と 3 - 1 = 2 個の bar(棒)の並べ方の個数に等しくなります。
なので、以下の二項係数(binomial coefficient)で求めることができます。

C((K - 3) + (3 - 1), 3 - 1) = C(K - 1, 2)

次に、制約 A, B, C <= N について考えます。

1. A, B, C の少なくとも1個が N + 1 以上になる場合の組み合わせの個数

先の a + b + c = K - 3 と同様に考えると、a + B + C = K - N の解の個数を求めることになります。

(a + N) + B + C = K => a + B + C = K - N C((K - N) - 1, 3 - 1) = C(K - N - 1, 2)

A, B, C のいずれかが N + 1 以上になる場合の組み合わせ個数は 3 * C(K - N - 1, 2) になるので、前述の制約 A, B, C >= 1 の組み合わせ個数から引きます。

C(K - 1, 2) - 3 * C(K - N - 1, 2)

2. A, B, C のうち2個が N + 1 以上の場合の組み合わせの個数

 1. では、A, B, C のうち2個が N + 1 以上の場合の組み合わせの個数を2回減算していますので、それを補正する必要があります。

(a + N) + (b + N) + C = K => a + b + C = K - 2 * N C((K - 2 * N) - 1, 3 - 1) = C(K - 2 * N - 1, 2) # A, B, C から 2 個を選ぶ組み合わせ数: C(3, 2) = 3 C(K - 1, 2) - 3 * C(K - N - 1, 2) + 3 * C(K - 2 * N - 1, 2)

3. A, B, C のすべてが N + 1 以上の場合の組み合わせ個数

A, B, C のすべてが N + 1 以上の場合の組み合わせ個数についても 2. と同様に補正を行います。

(a + N) + (b + N) + (c + N) = K => a + b + c = K - 3 * N C((K - 3 * N) - 1, 3 - 1) = C(K - 3 * N - 1, 2) C(K - 1, 2) - 3 * C(K - N - 1, 2) + 3 * C(K - 2 * N - 1, 2) - C(K - 3 * N - 1, 2)

最終的な公式は以下になります。

C(K - 1, 2) - 3 * C(K - N - 1, 2) + 3 * C(K - 2 * N - 1, 2) - C(K - 3 * N - 1, 2)

Python での実装は以下です。

python

1from math import comb 2 3N, K = map(int, input().split()) 4n = comb(K - 1, 2) 5if (m := K - N - 1) >= 2: n -= 3 * comb(m, 2) 6if (m := K - 2 * N - 1) >= 2: 7 n += 3 * comb(m, 2) 8 if (m := K - 3 * N - 1) >= 2: 9 n -= comb(m, 2) 10print(n)

投稿2025/09/17 20:27

編集2025/09/18 04:55
melian

総合スコア21491

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問