0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Paiza問題集】慣れた作業でも確認を怠ると、恐ろしい罠にハマるかもしれない。

Last updated at Posted at 2026-01-25

noteにもほぼ同じ内容で記事を投稿しています。

今日はPaiza問題集で、プログラミングの問題を解いていました。その中で最高のSランク問題をひとつクリアできたので、自分なりに振り返ってみたいと思います。

問題紹介

[ぴったり卵を生産 - その2] (https://paiza.jp/works/mondai/forest_contest_017/forest_contest_017__s_egg5)

今回解いたのは、「paizaの森練習問題コンテスト過去問題セット17」から、「 ぴったり卵を生産 - その2」。似たような問題が前にありました。

しかし前座の問題では n の上限は15だったのに対し、その2では上限が30。2 ^ 30 は10億くらいですね。この場合、さすがに総当たりは無理。お手上げーは悔しいので、色々考えて正解までこぎ着けました。

コード

コードの一部を載せます。

// Javascript
// 中略

  // 情報取得
  A = lines[ 1 ].split( " " ).map( Number );
  A.length = n;
  A.sort( function ( a , b ) {
      return a - b;
  });
  cut( A , 0 );
  
  // 再起呼び出し関数
  function search( arr , sum ) {
      // 終了条件(中略)
      
      else {
          // 取る方
          A2 = arr.concat();
          s2 = sum + A2[ 0 ];
          A2.shift();
          cut( A2 , s2 );
          search( A2 , s2 );
          
          // 取らない方
          A1 = arr.concat();
          A1.shift();
          search( A1 , sum );
      }
  }
  
  function cut( arr , sum ) {
      while ( ( arr.length > 0 ) && ( sum + arr[ arr.length - 1 ] > k ) ) {
          arr.pop();
      }
  }
  
 // 実行(中略)
 // 答えを出力(中略)

配列をコピーしまくって、数値を取るか取らないかの場合分けを行っています。合計値を計算しながら2パターンずつ試し、配列を削っていきます。

cut は「絶対に取れない大きな数値」を配列Aの上側から削除する関数。取ると sum が k を上回ってしまう場合は条件を満たせないので、そんな大きな値を消していきます。これにより考えるべき選択肢をさらに削り、計算量を減らします。

基本はそれぞれの数値を取るか取らないかを分けるだけで、総当たりと考え方は同じ。ただしこちらでは暫定の合計値を記憶しながら、取り得る数値を限定しています。選択肢を減らし解答を導きやすくすることで、計算量も現実的な数値になり、無事に正解できました。

ただ、もうちょっとスマートな解き方があるかもしれない。配列の切り取りも雑だし。配列の使い方、なかなか上手くならん。

おまけの話

実は100点のコードを出す前、得点は18点でした。そこに1行書き加えると、100点になるんですね。書き加えた行はどれでしょう?

答えは情報取得パートの、「 A.length = n 」です。

用意されている入力ケースの2行目において、最後にスペースが入っている場合、存在しないはずの A[ n ] に0が入ってしまいます。それで計算が狂って正解できなかったって訳です。最後についちゃった0を削除するために、情報を記録した配列Aの長さを n に限定する必要があったんですねー。

…いや、考え方はほぼ合ってるじゃねえかよ。20分くらい悩んだのは何だったんだ。Aに0があると狂うのかとか、JSの整数値の限界を超えたのかとか、色々考えたけど。実際はもっと原始的な話だった

慣れているところでも確認を怠ると、恐ろしい罠にハマることがあるんですねー。これからは情報取得ももっと丁寧にしようと思った、というお話でした。

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?