Paiza スキルチェック過去問題(PHP編) 日別訪問者数の最大平均区間 ~ランク B 相当~ 解いてみた。
はじめに
Paizaにて日別訪問者数の最大平均区間 (paizaランク B 相当)を解いてみました。
本番問題の解答・解説はNGですが、こちらに関しては、公開していいそうなのでまとめておきます。
(回答をPaizaでは再度閲覧できないため、備忘録的目的もあります。)
また、事前知識として標準入力の基本を知っておく必要がありますが、今回は割愛します。以下が参考になるかと思います。
https://paiza.jp/works/mondai/skillcheck_archive/max_range?language_uid=php
日別訪問者数の最大平均区間 (paizaランク B 相当)
以下が問題のリンクです。詳細はこちらでご確認ください。
https://paiza.jp/works/mondai/skillcheck_archive/max_range?language_uid=php
※問題文抜粋※
あなたは、とあるウェブサイトを管理していました。
ある連続したk日間、このウェブサイトでキャンペーンを行ったのですが、いつからいつまでの期間に行ったかを忘れてしまいました。幸い、ウェブサイトを運営していた全n日分のアクセスログが残っており、1日ごとの訪問者数が分かっています。
とりあえず、連続するk日の中で、1日あたりの平均訪問者数が最も多い期間を、キャンペーンを行った期間の候補だと考えることにしました。n日分の訪問者数のリストとキャンペーンの日数kが入力されるので、キャンペーンを行った期間の候補数と、候補の中で最も早い開始日を出力してください。
実際に入力される値:
5 3
1 2 3 2 1
ケースパターン3(躓いた部分メモ):
100 10
2 7 1 1 5 7 0 7 5 8 4 9 9 0 9 6 5 2 3 2 9 8 5 2 10 10 9 4 3 0 9 9 4 2 7 6 6 3 4 8 0 6 4 2 6 1 8 7 0 0 8 10 6 1 2 10 0 9 9 0 4 4 1 4 10 3 6 8 7 6 2 2 6 7 0 5 1 4 0 7 2 7 4 0 2 4 5 8 9 6 3 5 3 9 7 5 6 7 3 4
期待される出力:
1 2
ちなみに他ケースパターンはpaiza.ioで実行テストできます。
ブラウザ上で且つ無料で使えるのでかなり便利です◎
失敗例
解答コード:
<?php
// $nに全日数5、$kにキャンペーン日数3 を代入
fscanf(STDIN, "%d %d", $n, $k);
$visiter = fgets(STDIN);
// 数字で配列として1 2 3 2 1を代入
(int)$visiters = explode(" ",$visiter);
// k日分の訪問者数の和を必要な回数分求める
$slice_visiters = [];//[6,7,6]
for($i=0;$i<$n-$k+1;$i++){
// 全訪問者数からキャンペーン日数分の値のみ取り出す
$slice_visiter = array_slice($visiters,$i,$k);
//キャンペーン日数分の値の合計を出す
$slice_visiter = array_sum($slice_visiter);
//$slice_visitersへ配列を代入。配列に配列を代入してる。
array_push($slice_visiters,$slice_visiter);
}
//[6,7,6]を676に結合
$join = implode('', $slice_visiters);
$max = max($slice_visiters);//7
//substr_count( 検索対象の文字列, 検索する文字列 )
$count = substr_count( $join, $max );
//mb_strpos( 検索対象の文字列, 検索する文字列 )※0からカウントされる
$position = mb_strpos( $join, $max );
$ask_position = $position+1;
echo "$count $ask_position";
?>
約2時間の格闘の末、なんとかsuccessまで持っていきました。
絶対コードぐちゃぐちゃ(じぶんもよくわからない)。
もはや執念。。。
ところがどっこい。。。
不正解でした。
implode関数で結合しましたがよくよく考えたら、例えばmax値が15のときだと、1,5の配列も15としてみなされてカウントされちゃうのでだめですね。。。2桁の数字があると位置もずれるし。。。値が2桁になるケースを考えていなかった。。。
Oh my god!!
正解例
解答コード:
<?php
fscanf(STDIN, "%d %d", $n, $k);
$visiter = fgets(STDIN);
(int)$visiters = explode(" ",$visiter);
$slice_visiters = [];//[4,13,15,13]
for($i=0;$i<$n-$k+1;$i++){
// 全訪問者数からキャンペーン日数分の値のみ取り出す
$slice_visiter = array_slice($visiters,$i,$k);
//キャンペーン日数分の値の合計を出す
$slice_visiter = array_sum($slice_visiter);
//$slice_visitersへ配列を代入。配列に配列を代入してる。
array_push($slice_visiters,$slice_visiter);
}
//数字が連結しないようにカンマで区切る
$join = implode(',', $slice_visiters);
//配列の中の最大値を取得
$max = max($slice_visiters);
//最大値が出現する回数をカウント
$count = substr_count( $join, $max );
// 配列の中で最大値の最初の位置をキー値で取得※0からカウントされるので+1
$position = (int)array_search($max,$slice_visiters)+1;
echo "$count $position";
?>
失敗例のコードから諦めきれず、約1時間格闘した末なんとか正解まで辿り着きました。
ポイントは最大値が2桁の数字の際に、1桁の数字が連結してカウントされないように,(カンマ)でimplodeする際区切ったことと、array_search関数を使用して、配列の位置をキーで取得したことです。
参考になれば幸いです。
おわりに
値の数が多くなるとプログラミングを使うメリットを感じます。
ちゃんとPaizaランクBになれるよう頑張ります。
関連リンク
Paiza スキルチェック見本問題(PHP編)まとめ ~ランクC相当~
https://chobimusic.com/paiza_skillcheck_c/
Paiza スキルチェック見本問題(PHP編)まとめ ~ランクD相当~
https://chobimusic.com/paiza_skillcheck_d/
Paiza 標準入力セット(PHP編)まとめ ~ランクD相当~
https://chobimusic.com/paiza_standard_input/
Author And Source
この問題について(Paiza スキルチェック過去問題(PHP編) 日別訪問者数の最大平均区間 ~ランク B 相当~ 解いてみた。), 我々は、より多くの情報をここで見つけました https://qiita.com/masaru1125/items/5ca2e67c47d525f17b91著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .