
これがスキルチェック過去問セットで最後まで残っていた問題です。やっと通りました。
<?php
// 自分の得意な言語で
// Let's チャレンジ!!
$s = explode(" ",trim(fgets(STDIN)));
$num = $s[0];
$word_num = $s[1];
$remark_num = $s[2];
for($i=0; $i<$word_num;$i++){
$words[] =trim(fgets(STDIN));
}
//print_r($words);
for($i=0; $i<$remark_num;$i++){
$remarks[] =trim(fgets(STDIN));
}
//print_r($remarks);
//解答順
$people = array();
for($i=0; $i<$num; $i++){
$people[$i] = $i;
}
//print_r($people);
$first_answer = true;//最初の解答者か
for($i=0; $i<$remark_num; $i++){
$hoge = $remarks[$i];
$flag01=false;
$flag02=false;
$flag03=false;
for($j=0; $j<count($words); $j++){
if($hoge==$words[$j]){
$flag01=true;
$match_words_number = $j;
}
}
if($first_answer==true){
$flag02=true;
$first_answer=false;
}else{
$hoge_first = mb_substr($hoge,0,1);
$hoge_before_last = mb_substr($remarks[$i-1],-1,1);
if($hoge_first == $hoge_before_last){
$flag02=true;
}
}
if(mb_substr($hoge,-1,1)!="z"){
$flag03=true;
}
//判定
if($flag01==true && $flag02==true && $flag03==true){
//echo("よいかいとう\n");
unset($words[$match_words_number]);
$words = array_merge($words);
//echo("wordをへらした\n");
//print_r($words);
//解答順をかえたい
$temp = $people[0];
array_shift($people);
array_push($people,$temp);
//echo("解答順がかわった\n");
//print_r($people);
}else{//なにかまちがったらしい
$first_answer=true;
array_shift($people);// 冒頭をひとつけす
//echo("解答人数がかわった\n");
//print_r($people);
}
}
//出力
asort($people);
echo(count($people)."\n");
foreach($people as $value){
echo(($value+1)."\n");//配列は0はじまりなので
}
?>
難しかったのは、「現在の解答者」をどう表現するかです。
回答者は解答をまちがえて減る可能性もあります。
なので、配列に解答人数ぶん解答者番号をいれておき、
・解答が正解したら「配列の冒頭を$tempに一時格納、冒頭を消す、末尾に$tempを追加」(すなわち2人目が1人目に繰り上がる)
・解答が不正解なら、その解答者を配列から消し、キーを振りなおす(というか、array_shiftは自動でそうなる)
という挙動をしています。
これなら、「常に配列の冒頭が現在の解答者」ということになり、同時に配列内に残っているのが生き残りの解答者となります。
最後に配列内にのこっている要素(生き残り)を出力しておわりです。


paiza スキルチェック過去問セット php
https://paiza.jp/works/mondai/skillcheck_archive/problem_index?language_uid=php
1+