
この問題は丁寧な動画解説があるのですが、私にはちょっと難しかったので、
すこしだけ別の方法を取ってみました。
<?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に足して最終的に出力しました。

問題はこちら
https://paiza.jp/works/mondai/skillcheck_sample/problem_index?language_uid=php
2+