

あなたは、とあるウェブサイトを管理していました。
paiza スキルチェック過去問題より
ある連続したk日間、このウェブサイトでキャンペーンを行ったのですが、いつからいつまでの期間に行ったかを忘れてしまいました。
幸い、ウェブサイトを運営していた全n日分のアクセスログが残っており、1日ごとの訪問者数が分かっています。
とりあえず、連続するk日の中で、1日あたりの平均訪問者数が最も多い期間を、キャンペーンを行った期間の候補だと考えることにしました。
n日分の訪問者数のリストとキャンペーンの日数kが入力されるので、キャンペーンを行った期間の候補数と、候補の中で最も早い開始日を出力してください。
この手の問題を考えるとき、頭に浮かぶ図がこれです。
入力例
5 3
1 2 3 2 1

ざっくりしたスプレッドシートで申し訳ありません。
範囲内に連続したかたまりがあり、それが1つずつ横にスライドしている。
スライドできなくなったらそこでおわり。
そういうイメージです。

<?php
    // 自分の得意な言語で
    // Let's チャレンジ!!
    
    /*
    n日分の訪問者数のリストとキャンペーンの日数kが入力されるので、
    キャンペーンを行った期間の候補数と、候補の中で最も早い開始日を出力してください。
    */
    $s = explode(" ",trim(fgets(STDIN)));
    $num = $s[0];//全体の日数
    $cam_num = $s[1];//キャンペーンの日数
    
    $days = explode(" ",trim(fgets(STDIN)));//日ごとの訪問数
    //print_r($day);
    
    //キャンペーン期間の訪問者合計をだす
    for ($i = 0; $i < $num-$cam_num+1; $i++) {
        $sum[$i]=0;//reset 連続するキャンペーン日数の訪問数の合計
        
        for ($j = 0, $k=$i; $j < $cam_num; $j++,$k++) {
            $sum[$i]=$sum[$i]+$days[$k];
        }
    }
    
    //print_r($sum);
    $max = max($sum);
    //echo($max);
    
    $max_num = 0;//reset キャンペーンを行った期間の候補数
    
    //最大値をもっている日程を探す
    foreach($sum as $key=>$value){
        if($value==$max){
            $max_num++;
            $answer[]=$key;
        }
    }
    echo($max_num." ");
    //print_r($answer);
    
    $first_answer = $answer[0]+1;//候補の中で最も早い開始日/配列が0はじまりのため1を足す
    echo($first_answer."\n");
    
?>
構造としては、
- 日にちの訪問者を配列に入れておく($days)
 - キャンペーン日数(この場合3日)のかたまり【黄色部分】を1つずつ横にずらして取得したい
 - よってforの始まりは$i = 0; ループ範囲は$i < $num-$cam_num+1;(全日程numからキャンペーン日数$cam_numを引き1を足す) $i++
 - その合計値を配列に入れておく($sum) (なお$sumのキーはキャンペーン候補開始日にもなっています)
 - $sumの最大値をもっているものが「もっともキャンペーンの3日というかたまりのなかで訪問者を取得している」ということになる
 - 『キャンペーンを行った期間の候補数』が解答で求められているため、候補日は複数あると仮定し、最大値を持っているものの数を変数に格納($max_num)
 - 同時に最大値をもっているもののキー(すなわち開始日候補)を$answerに格納
 - 『候補の中で最も早い開始日を出力してください。』ということなので、$answer[0](配列のトップ)を出したいが、配列は0始まりで日にちは1始まりのため+1して出力
 
そういう流れになっています。

二重forで処理するのですが内側のforにはちょっと変数に仕掛けがいります。
$j =$i; でループを始めてしまうと「連続した3日」が、2回目のループの時には「連続した2日」、さらに「連続した1日」と目減りします。これはよくない。
よって$kをかませる必要がありました。
ご参考になれば幸いです。
paiza スキルチェック過去問題セット
https://paiza.jp/works/mondai/skillcheck_archive/problem_index?language_uid=php
3+			
初コメ失礼します。
PHP学習中なのですが、
for ($j = 0, $k=$i; $j < $cam_num; $j++,$k++) {
$sum[$i]=$sum[$i]+$days[$k];
}
ここの部分ですが、なぜ$kを噛ませる事で、連続した三日を維持出来るのでしょうか?
結構、難しいなあと感じてしまいました。
あやぼうさんお疲れ様です。
for ($j = 0, $k=$i; $j < $cam_num; $j++,$k++) {この部分ですが、最初、
for ($j=$i; $j < $cam_num; $j++) {と記述したんですよ。
結果どうなったかというと、
「外側のfor文のカウント」が進み、$i=1、$i=2とすすむたび、
ちょうどこう記述した形になってしまったんです。
for ($j=2; $j < $cam_num; $j++) {お気づきでしょうか?
こうなると$cam_numは定数の3ですので、
この内側のループは本来3日あるはずのキャンペーン期間を、
「2からはじめて3より小でおわる」1日分で済ませて終了しまいます。
内側のループは「キャンペーン期間」3日分でちゃんと回してほしい。
よって$jは「常に0から始めて」「3より小で」ループを終わらせる。
一方スライドする日付(開始日)も欲しい。それは$iに連動しています。
よって2つめの$kが登場し、$k=$i;となっています。
(そしてforループの終了条件は$jが持っています。$kは影響を受けません。 これによって3日が維持されます。)
もっとスマートで分かりやすい記述があるかもしれません。 私も万事勉強中ですのでご容赦ください。 ほんのご参考になれば幸いです!