LoginSignup
1
0

More than 5 years have passed since last update.

アルゴリズム問題 Bウサギジャンプ

Last updated at Posted at 2018-07-25

問題

いくつかのしげみにはうさぎがいます。1 箇所のしげみに 2 羽以上のうさぎがいることはありません。
今、全体で M 羽のうさぎがいます。ただし、うさぎの数は必ずしげみの数より少ないものとします。
image.png

うさぎに 1, 2, ..., M と番号をつけたとき、それぞれのうさぎは次のルールに従って今いるしげみから別のしげみへジャンプします。

まず、1 番目のうさぎが、今いるしげみから反時計回りに見て最も手前にある空いているしげみにジャンプする
次に、2 番目のうさぎが、今いるしげみから反時計回りに見て最も手前にある空いているしげみにジャンプする
……
最後に、M 番目のうさぎが、今いるしげみから反時計回りに見て最も手前にある空いているしげみにジャンプする

これらのジャンプが K セット終わったとき、すなわち、すべてのうさぎがちょうど K 回ジャンプしたとき、それぞれのうさぎがどのしげみにいるかを求めてくだ

入力

N M K
r_1
r_2
...
r_M

1 行目には 3 つの整数 N, M, K が入力されます。
N はしげみの個数を、M はうさぎの総数を、K はそれぞれのうさぎがジャンプする回数を表します。

続く M 行には、うさぎの位置が入力されます。
r_i は i 番目のうさぎがいるしげみの番号を表します。

出力

出力は M 行からなります。
i 行目には、K セットのジャンプが終わったあとに i 番目のうさぎがいるしげみの番号を出力してください。
(i = 1, 2, ..., M)

回答コード (1,7h 10%正解)

# 自分の得意な言語で
# Let's チャレンジ!!

# 自分の得意な言語で
# Let's チャレンジ!!
input_lines = gets.split(" ").map(&:to_i)#5 2 2


shigemi=input_lines[0]
usagi = input_lines[1]
jump = input_lines[2]

usa_iti=[false]*shigemi

usagi.times do
    ima_shigemi = gets.to_i
    index = ima_shigemi-1
    usa_iti[index] = ima_shigemi
end
#--初期のウサギの位置



jump.times do
    1.upto(usagi) do|usagi| #1~usagi番目まで順番に現在の位置から次のfalseに移って,元いた茂みをfalseにする 
        ima_index = usa_iti.index(usagi)#1ウサギのインデックス番号を取得
        next_pos = usa_iti[ima_index+1..-1].find_index{|t| t==false} #ウサギの位置より先をみてfalseがあればインデックス取得
        usa_iti[ima_index] = false#今の所を空きにする
        #ここで最大値まで見て空きが無い場合、next_posはnilLで帰ってくるので0からさがす
        if next_pos == nil
            next_pos = usa_iti[0..ima_index].find_index{|t| t==false}
            usa_iti[next_pos] = usagi
        else #falseがあるなら見つけたインデックス番号で参照してそれをusagi番に塗り替える
            sa = usa_iti[0..ima_index].count 
            usa_iti[next_pos + sa] = usagi #next_posが「ウサギの位置~最後の茂み」の配列から得たインデックスになっているため「最初~ウサギ」の分を足す

        end
    end

end
#ジャンプしきったら1から順にウサギのいる茂みののインデックス番号を表示するプログラム
1.upto(usagi){|u|
    ans=usa_iti.index(u)
    puts ans+1#茂みは1スタートだからインデックス+1
}    



解説

結果をみて驚いた。最初のテストケースしか正解していない。
見直したところ原因がすぐわかった。

入力に注意をはらってなかった。
入力される値は「ウサギの数だけ、今ウサギがいる茂みの番号が与えられる」
というもので、上記のコードではもし一匹目が2番目の茂みからスタートしていればすでにそれでエラーになるというものだった

問題の部分
 1.upto(usagi) do|usagi| #1~usagi番目まで順番に現在の位置から次のfalseに移って,元いた茂みをfalseにする

考えた結果、出力は「入力が行われたウサギの順番に、最後にいる茂みの番号」
であるので最初に得たウサギの通り番号は最後まで保持しなければならないと考え、ジャンプを行うコード部分には触れず、初期のusa_iti配列のウサギに通り番号を1~usagi持たせることにした。

修正コード(50点)

# 自分の得意な言語で
# Let's チャレンジ!!

# 自分の得意な言語で
# Let's チャレンジ!!
input_lines = gets.split(" ").map(&:to_i)#5 2 2


shigemi=input_lines[0]
usagi = input_lines[1]
jump = input_lines[2]

usa_iti=[false]*shigemi

usagi.times do
    ima_shigemi = gets.to_i
    index = ima_shigemi-1
    usa_iti[index] = ima_shigemi
end
#--初期のウサギの位置
n=1
usa_iti.each_with_index do|usa , i|
    if !usa == false
        usa_iti[i] = n
        n+=1
    end
end


jump.times do
    1.upto(usagi) do|usagi| #1~usagi番目まで順番に現在の位置から次のfalseに移って,元いた茂みをfalseにする 
        ima_index = usa_iti.index(usagi)#1ウサギのインデックス番号を取得
        next_pos = usa_iti[ima_index+1..-1].find_index{|t| t==false} #ウサギの位置より先をみてfalseがあればインデックス取得
        usa_iti[ima_index] = false#今の所を空きにする
        #ここで最大値まで見て空きが無い場合、next_posはnilLで帰ってくるので0からさがす
        if next_pos == nil
            next_pos = usa_iti[0..ima_index].find_index{|t| t==false}
            usa_iti[next_pos] = usagi
        else #falseがあるなら見つけたインデックス番号で参照してそれをusagi番に塗り替える
            sa = usa_iti[0..ima_index].count 
            usa_iti[next_pos + sa] = usagi #next_posが「ウサギの位置~最後の茂み」の配列から得たインデックスになっているため「最初~ウサギ」の分を足す

        end
    end

end
#ジャンプしきったら1から順にウサギのいる茂みののインデックス番号を表示するプログラム
1.upto(usagi){|u|
    ans=usa_iti.index(u)
    puts ans+1#茂みは1スタートだからインデックス+1
}    

コード自体のエラーは取除く事ができたが
それでも出力失敗で50点。
原因わからずなので私はあきらめた。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0