質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.46%
Python

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

Q&A

解決済

2回答

466閲覧

AtCoder beginner contest 227 B の問題について

kibagon

総合スコア12

Python

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

0グッド

0クリップ

投稿2021/11/13 15:42

前提・実現したいこと

AtCoderのBeginner Contest 227の問題です。

1 から N の番号がついた N 人の人がいます。

人 i はキーエンス本社ビルの建築面積を Si 平方メートルであると予想しました。

キーエンス本社ビルは下図のような形をしています。ただし、a,b はある 正の整数 です。
つまり、キーエンス本社ビルの建築面積は 4ab+3a+3b 平方メートルと表されます。

N 人のうち、この情報のみによって、予想した面積が確実に誤りであるとわかる人数を求めてください。

制約
1 ≤ N ≤ 20
1 ≤ Si ≤ 1000
入力に含まれる値は全て整数である

発生している問題・エラーメッセージ

5
10 20 39 10 10

を入力した際になぜか2となってしまう(本来なら20のみ4ab+3a+3bの形で表せないので1となるはず)のですが、理由がわかりません。

4
10 20 39 10 だと正しく1が出力されるのですが、上の例だとうまくいかない理由を教えていただけると幸いです。よろしくお願いいたします。

該当のソースコード

N = int(input()) S = list(map(int, input().split())) for a in range(1, 143): for b in range(1, 143): x = 4 * a * b + 3 * a + 3 * b for i in S: if i == x: S.remove(i) print(len(S))

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答2

0

ベストアンサー

Python のドキュメントに説明があります。

8.3. for 文

注釈

ループ中でのシーケンスの変更には微妙な問題があります(これはミュータブルなシーケンスのみ、例えばリストで起こり得ます)。どの要素が次に使われるかを追跡するために、内部的なカウンタが使われており、このカウンタは反復のたびに加算されます。このカウンタがシーケンスの長さに達すると、ループは終了します。このことから、スイートの中でシーケンスから現在の(または以前の)要素を除去すると、(次の要素の位置が、既に処理済みの現在の要素のインデックスになるために)次の要素が飛ばされることになります。同様に、スイートの中でシーケンス中の現在の要素以前に要素を挿入すると、現在の要素がループの次の週で再度扱われることになります。こうした仕様は、厄介なバグにつながります。これは、シーケンス全体のスライスを使って一時的なコピーを作ることで避けられます。例えば次のようにします:

for x in a[:]: if x < 0: a.remove(x)

とはいうものの、x と等しくない要素を残せば良いのですから、以下の様に書き換えても良いはずです。

python

1 # for i in S: 2 # if i == x: 3 # S.remove(i) 4 S = [i for i in S if i != x]

投稿2021/11/13 17:09

melian

総合スコア19865

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

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

0

python

1 for i in S: 2 if i == x: 3 S.remove(i)

で、Sからiを削除することでループの回転数が変わるからです。
以下のようにコピーを使えば、この問題は起きません。

python

1>>> N=5 2>>> S = [10,20,39,10,10] 3>>> S2 = S.copy() 4>>> 5>>> for a in range(1, 143): 6... for b in range(1, 143): 7... x = 4 * a * b + 3 * a + 3 * b 8... for i in S: 9... if i == x: 10... S2.remove(i) 11... 12Traceback (most recent call last): 13 File "<stdin>", line 6, in <module> 14ValueError: list.remove(x): x not in list 15>>> print(S2) 16[20]

投稿2021/11/13 16:18

編集2021/11/13 16:20
ppaul

総合スコア24666

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問