C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で解く!面白い瞬間の間隔から試合の視聴時間を求めるアルゴリズム

n個の要素を持つ配列Aがあるとしましょう。Amalは90分間の試合を観戦したいと考えており、試合中に休憩はありません。試合の各1分は「面白い」または「退屈な」のどちらかに分類され、15分連続して退屈な時間が続くと、Amalは直ちにテレビの電源を切ります。配列Aには、面白くなる瞬間の経過時間(分)がn個記録されています。このとき、Amalが合計で何分間試合を視聴することになるのかを求めます。

例えば、入力が A = [7, 20, 88] の場合、出力は 35 になります。20分までは面白い瞬間が15分以内の間隔で訪れるため視聴を続けられますが、その後88分まで次の面白い瞬間が訪れないため、20 + 15 = 35分の時点でテレビを切ることになるからです。

解法のアプローチ

この問題の鍵となるのは、隣り合う面白い瞬間の間隔が15分を超えるかどうかという点です。間隔が15分以下であれば視聴を継続し、15分を超えた時点で「最後の面白い瞬間+15分」が視聴終了时刻となります。最後まで15分を超える間隔が現れなかった場合は、試合終了の90分がそのまま答えになります。

手順

サイズ100の配列 a を定義する
n := A のサイズ
i := 1 で初期化し、i <= n の間 i を1ずつ増やしながら繰り返す:
    a[i] := A[i - 1]
    もし a[i] - a[i - 1] > 15 ならば:
        ループから抜ける
(a[i - 1] + 15) と 90 のうち小さい方を返す

C++での実装例

理解を深めるために、以下の実装例を見てみましょう。

#include <bits/stdc++.h>
using namespace std;
int solve(vector<int> A){
    int i, a[100];
    int n = A.size();
    for (i = 1; i <= n; i++){
        a[i] = A[i - 1];
        if (a[i] - a[i - 1] > 15)
            break;
    }
    return min(a[i - 1] + 15, 90);
}
int main(){
    vector<int> A = { 7, 20, 88 };
    cout << solve(A) << endl;
}

入力

{ 7, 20, 88 }

出力

35

コードのポイント

配列の先頭 a[0] は初期値0(試合開始時点)として扱われます。そのため、最初の面白い瞬間が7分であれば、開始からの間隔は15分以内となり、問題なく視聴を続けられます。ループ途中で break が発生した場合、変数 i は15分を超える間隔が見つかった位置を指しているため、a[i - 1] が「最後の面白い瞬間」の時刻になります。そこへ15を加え、min 関数で90分との小さい方を選ぶことで、正しい視聴時間が求まります。計算量は O(n) と非常に効率的です。

  1. 【C++】差がnとなる2つの合成数を見つける方法

    整数 n が与えられたとき、その差がちょうど n になる2つの合成数(素数ではない数)a と b を求める問題を考えます。 例えば、入力が n = 512 の場合、出力は 5120 と 4608 となります。実際に確認すると、5120 − 4608 = 512 であり、両方とも合成数なので条件を満たしています。 解法のアプローチ この問題は一見すると探索が必要そうに思えますが、実は非常にシンプルな数学的性質を利用すれば、即座に答えを導き出せます。 答えは、10 × n と 9 × n を出力するだけです。 なぜこの方法が有効なのか? 10 × n は必ず 10 を約数に持つため、常に合成

  2. C++で2^(2^A) % Bを効率的に計算する方法

    このチュートリアルでは、2^(2^A) % Bという式の値を求めるプログラムをC++で作成していきます。一見すると巨大な指数計算が必要に思えますが、再帰関数を使うことで、実際に巨大な数を計算することなく効率的に答えを求められます。ここでは、その考え方と実装手順を順番に解説します。解き方の手順この問題は、次のような性質を利用して再帰的に解くことができます。A と B の2つの引数を受け取る再帰関数を作成します。A が 1 の場合、2^(2^1) % B = 4 % B となるため、4 % B を返します(ベースケース)。それ以外の場合は、引数を A - 1 として関数を再帰的に呼び出します。得ら