paiza スキルチェック見本問題セット 「長テーブルのうなぎ屋 PHP編」解答例

この問題は丁寧な動画解説があるのですが、私にはちょっと難しかったので、
すこしだけ別の方法を取ってみました。

<?php
    // 自分の得意な言語で
    // Let's チャレンジ!!
    
    /*
    1行目にはn(座席数)とm(グループ数)が半角スペース区切りで入力されます。
    i+1行目(1≦i≦m)には2個の整数a_i(グループの人数)とb_i(着席開始座席番号)が半角スペース区切りで入力されます。
    */
    
    //get data
    
    $s = trim(fgets(STDIN));
    $s = str_replace(array("\r\n","\r","\n"), '', $s);
    $s = explode(" ", $s);
    //echo "hello = ".$s[0]." , world = ".$s[1]."\n";
    
    $seat_num = $s[0];
    $group_num = $s[1];
    
    
    //proseccing
    
    //seatの数だけ配列の要素が欲しい
    $seats = array();
    for ($i = 1; $i < $seat_num+1; $i++) {
        $seats[$i] = 1;//座り可能
    }
    //print_r($seats);
    
    $ok_people = 0;//無事に着席できた人数
    
    
    for ($i = 0; $i < $group_num; $i++) {
        $t = trim(fgets(STDIN));
        $t = str_replace(array("\r\n","\r","\n"), '', $t);
        $t = explode(" ", $t);
        //echo "hello = ".$t[0]." , world = ".$t[1]."\n";
        
        $people_num = $t[0];//団体の人数
        $first_seat = $t[1]  ;//座り始めの座席番号
        //echo($i."番目の団体 ".$people_num."人, 座席".$first_seat."\n");
        
        
        //$first_seatがあいているかどうか
        $temp_seats = $seats;//seatsを一時転写
        $flag_cannot = false;//reset 座れるかどうか

        
        for($j=$first_seat; $j<$people_num + $first_seat; $j++){
            
             //座席番号が座席数を超えるか
             if($j > $seat_num){
                 $k = $j - $seat_num;
             }else{
                 $k = $j;
             }
            
            
            if($seats[$k]==1){
                $temp_seats[$k]=2;//席を埋める
            }else{
                $flag_cannot= true;
            }
        }
        
        
        if($flag_cannot==false){//全員座れた
            //echo("全員座れた\n");
            $seats = $temp_seats;//転写を本来のに戻す
            $ok_people += $people_num;
            //print_r($seats);
        }else{
            //echo("cannot sit\n");
        }     
        
    }

    //output

    echo($ok_people."\n");

?>

配列seatsに、座席数ぶん要素をつくって、値1を入れておきます(空席の印)

団体客がきたら、座り始めの席番号から、人数分forで判定、
配列seatsの該当する場所が1だったら2(着席の印)にします。

しかし座れなくてキャンセルになる場合もあります。
その場合、seatsの値が途中まで2になっているのはまずい。よってseatsを転写した仮配列「temp_seats」に2を入れます。
全員座れたら仮配列を本配列に戻します、キャンセルが出たら本配列には戻しません。

問題は座席が輪になっていることです。forの回し始めは「団体客が指定する座席番号」、回し終わりは「座席番号+団体人数」です。よってこの値($j)が座席数を超えたら、店の座席数を引きます。これで指定座席番号が輪の初めになります。($k)
$jの値が座席数を超えないならそのまま$kとすればいい。この$kを座席番号として判定します。
座れた人数を$ok_peopleに足して最終的に出力しました。

kue

問題はこちら

https://paiza.jp/works/mondai/skillcheck_sample/problem_index?language_uid=php

2+

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です