paiza Aランクレベルアップメニュー「最短の区間 PHP編」解答例

しゃくとり法を使う問題なんですが、しゃくとりになっていません(たぶん)
通ったのはたまたまの可能性があります。
とくに「尺を短くする」処理が違うのではという予感がする。
よくない解答例だと思いますが、ほんのご参考まで&自分のおぼえがきにコードを置いておきます。

<?php
    // 自分の得意な言語で
    // Let's チャレンジ!!

    /*
    数列 A の要素数 N と値 M ,その要素 A_1, A_2 ... A_N が与えられます。
    要素の和が M 以上となるような A の部分列の最短の長さを求めてください。
    そのような部分列が存在しない場合は −1 を出力してください。
    */
    
    //情報取得
    $input = explode(" ",trim(fgets(STDIN)));
    $num = $input[0];
    $m = $input[1];
    
    $hoges = explode(" ",trim(fgets(STDIN)));
    //print_r($hoges);
    
    
    //累積和を求める
    $sum[0] = 0;
    for($i=0; $i<$num; $i++){
        $sum[$i+1] = $sum[$i] + $hoges[$i];
    }
    //array_shift($sum);//不要な冒頭要素を消す → いや、敢えて消さない
    //print_r($sum);
    
    
    //処理
    $ok_flag = false; //reset
    $right = 0;//区間の右端
    
    for ($left = 0; $left < $num; $left++) {
        while($right < $num){
            $right++;
            //echo("ただいまのleft,right ".$left.",".$right." ");
            //$foo = $sum[$right] - $sum[$left];
            //echo("rightsum-leftsum ".$foo."\n");
            
            if($sum[$right]-$sum[$left] >= $m){
                //echo("条件一致\n");
                $ok_flag = true;
                $save[] = $right-$left;
                $left++;
                $right = $left;
            }
        }
    }
    //print_r($save);
    
    
    //出力
    if($ok_flag==false){
        echo(-1);
    }else{
        echo(min($save));
    }


?>

paizaさんの「解説(解法のポイント)」とは挙動が違います。これでは「右端を固定して左を縮める」をしていないので。

おそらく・・・「条件一致」したら、右端である$rightを減らすような処理を目指すのかと思うのですが。

つまりこのコードでは、しゃくとり法の利点であるはずの、メモリ節約がたぶんできていないだろうし、条件「以下の」ものにも対応できないだろうと思う。

kue

尺取り法おぼえがき
こういうのをいう。右端を固定し左を縮めるのがキモらしいです。

※本来半開区間で考えるらしいのですが、理解をやさしくするためすこし変えてあります。

あと上のグラフ、抜けがありました。
4,12,3のあとに12,3と3もあるはずですね。2行抜かしてしまった。

参考1:しゃくとり法 (尺取り法) の解説と、それを用いる問題のまとめ

https://qiita.com/drken/items/ecd1a472d3a0e7db8dce

参考2:らんそうるいさんのコード
ありがとうございました。

問題一覧はこちら :
paizaAランクレベルアップメニュー(php)

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

0

コメントを残す

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