平成31年春期午後問11

午前試験免除制度対応!基本情報技術者試験のeラーニング【独習ゼミ】
mさん
(No.1)
https://www.fe-siken.com/kakomon/31_haru/pm11.html
設問2のfで
「仮に i に3が入るとして、
history.get(2)の値がNOATH
history.get(3)の値がSOUTH」

という例がありますが、そもそもi=3の時、なぜこうなるのかわかりません。
また、ここから2番目と3番目を削除する理由がわかりません。

教えてください。よろしくお願いします。
2020.10.24 11:16
QMさん
(No.2)
例として使う i は何でもいいし、値も何でもいいです。
3 や SOUTH でなくても構いません。
正反対の向き(ここでは NORTH と SOUTH)が連続しているという点だけがポイントです。

f の行は、問題文にある
「直前の升に戻る(正反対の方角に向きを変えて進む)ことなく」
を満たすためにやっている処理です。

ある向きに進んだ後、すぐ正反対の向きに進んだ(元の場所に戻った)なら、この動きは削除しましょう、ということです。
2020.10.24 15:16
Bun-Kさん
(No.3)
私も初め何が何だか分からなかったです。
まずこの挿入された処理が何なのかという説明がいると思うのですが、
これは迷路のゴールまでたどり着いたあと、履歴の中から無駄な動きを削除して、最適なルートを得ようとするものです。履歴を改ざんして迷わなかったことにしてしまおうという感じです。
無駄な動きとは北に移動した直後に南に戻るとか、東に移動した直後に西に戻るとかです。
[NORTH, NORTH, NORTH,SOUTH,EAST]みたいな履歴があった場合、3番目のNORTHと4番目のSOUTHの動きは無駄なので、消しちゃって、[NORTH, NORTH,EAST]にしてしまおうということです。
で、問題文の図2に上がっている方角のリストはこういう無駄な動きを削除した後のリストなので、何の参考にもなりません、無視してOK。
解説では例として、履歴の配列の中の2番目と3番目にそういう無駄な動きが入っていた場合を想定して書かれています。つまりhistory(2)にNORTH、history(3)にSOUTHという無駄な動きが入っているので、これを削除したいという例です。
で、どういうコードでそれをやろうとしているのかというと、これがなかなかやらしいのですが、同じ添字の配列を2回削除することでこの無駄な動き、NORTH、SOUTHを消そうとしています。配列の要素を消すと、それ以降の要素が前に詰められるので、同じ添字の配列を2回消すと初めに消した要素とその一個後ろの要素が消されることになります。
じゃあhistory(2)とhistory(3)を消したい時、このforループの中でどう指定してやればいいか、history(i)を2回消すのか、、history(i+1) なのか、history(i-1) なのかというのが設問です。
削除の判断条件がhistory(i)とhistory(i-1)を比較しているので、history(2)とhistory(3)が削除対象になるとすると、iが3の時ですよね。iが3の時にhistory(2)とhistory(3)を消したいわけです。
なので入れるのはi-1です。
1回目の history.remove(i-1) でhistory(2)のNORTHが消えて、history(3)だったSOUTHがhistory(2)に入ってきます。
で、もう1回 history.remove(i-1)すると、さっきまでhistory(3)だったのにhistory(2)なったSOUTHが消えて、めでたく無駄な2つの動きが履歴から削除されます。
上にあげた[NORTH, NORTH, NORTH,SOUTH,EAST]という配列に対してこの処理を行った場合、
1回目のhistory.remove(i-1)で
[NORTH, NORTH,SOUTH,EAST]になり、
2回目のhistory.remove(i-1)
[NORTH, NORTH, EAST]になるわけです。

お分かり頂けましたでしょうか。
2020.10.24 17:04

返信投稿用フォーム

スパム防止のために初投稿日から10日以上経過したスレッドへの書き込みは禁止しています。

その他のスレッド


Pagetop