【スキルチェック過去問題セット】> みんなでしりとり (paizaランク B 相当) [難易度: 2026 ±17]
※リンク先へ移動するためには[paiza]へのログインが必要です。
あなたは友達たちと N 人でしりとりを行うことにしました。
1 人目、 2 人目、...、 N 人目、 1 人目、2 人目、... という順序で発言をします。
ここで、それぞれの人は、次に挙げる 4 つのしりとりのルールを守って発言をする必要があります。
1. 発言は、単語リストにある K 個の単語のうちのいずれかの単語でなければならない。
2. 最初の人以外の発言の頭文字は、直前の人の発言の最後の文字と一緒でなければならない。
3. 今までに発言された単語を発言してはならない。
4. z で終わる単語を発言してはならない。
ここで、発言の途中で上のルールを破った場合、ルールを破った人はしりとりから外れます。
そして、その人を抜いて引き続きしりとりを続けていきます。このとき、後続の人は、ルール 2 を守る必要はありません。
N 人がしりとりを行ったログが M 行分与えられます。
このとき、M 回の発言が終わった後、しりとりから脱落せずに残っている人のリストを表示するプログラムを書いてください。
入力値(例)
3 6 7
a
aloha
app
az
paiza
warp
app
paiza
a
aloha
az
warp
paiza
出力値(例)
1
3
解答例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
<?php //ルールの関数を作る //ルール1. 発言は、単語リストにある K 個の単語のうちの //いずれかの単語でなければならない。 function rule1($word_list, $v) { return in_array($v, $word_list); } //ルール2. 最初の人以外の発言の頭文字は、 //直前の人の発言の最後の文字と一緒でなければならない。 function rule2($v, $before_word, $pass_rule2) { return $pass_rule2 or $before_word[-1] == $v[0]; } //ルール3. 今までに発言された単語を発言してはならない。 function rule3($current_log, $v) { return (!in_array($v, $current_log)); } //ルール4. z で終わる単語を発言してはならない。 function rule4($v) { return $v[-1] != "z"; } function next_number($alive, $now_number) { while(true) { if($now_number >= count($alive)) { $now_number = 0; } if($alive[$now_number]) { return $now_number; } $now_number += 1; } } list($n, $k, $m) = explode(" ", trim(fgets(STDIN))); for($i=0; $i<$k; $i++) { $word_list[] = trim(fgets(STDIN)); } for($i=0; $i<$m; $i++) { $log[] = trim(fgets(STDIN)); } //生存者をtrueとした配列を作る、脱落したらfalseにする $alive = array_fill(0, $n, true); //print_r($alive); $now_number = 0; $current_log = []; $before_word = " "; //最初の人はルール2をパスしてよい $pass_rule2 = true; for($i=0; $i<$m; $i++) { $v = $log[$i]; if(rule1($word_list, $v) and rule2($v, $before_word, $pass_rule2) and rule3($current_log, $v) and rule4($v)) { $pass_rule2 = false; } else { $alive[$now_number] = false; $pass_rule2 = true; } //発言したワードを保存しておく配列を作る $current_log[] = $v; $now_number = next_number($alive, $now_number+1); $before_word = $v; } //print_r($alive); echo array_sum($alive). "\n"; for($i=0; $i<count($alive); $i++) { if($alive[$i]) { echo ($i+1). "\n"; } } ?> |