LoginSignup
0
3

More than 3 years have passed since last update.

Paiza スキルチェック過去問題(PHP編) 日別訪問者数の最大平均区間 ~ランク B 相当~ 解いてみた。

Posted at

はじめに

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で実行テストできます。

ブラウザ上で且つ無料で使えるのでかなり便利です◎

https://paiza.io/ja


失敗例

解答コード:
<?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/

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3