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

C++で解く:クレイジーワードプロセッサの問題――n文字入力後に画面へ残る文字数を求める

要素数 n の配列 A と、もう一つの値 c が与えられているとします。システムには「クレイジーなワードプロセッサ」が存在し、文字を入力することはできますが、連続して c 秒間入力を行わないと、それまでに書いたすべての文字が消去されてしまいます。A[i] は i 番目の文字を入力した時刻を表します。このとき、n 文字すべてを入力し終えた後、画面に残る文字数の合計を求める必要があります。

例えば、入力が A = [1, 3, 8, 14, 19, 20]、c = 5 の場合、出力は 3 になります。時刻 8 の時点では画面上に 3 文字が表示されていますが、その後時刻 13 ですべての文字が消去されます。続いて時刻 14 と 19 にさらに 2 文字が入力され、最後に時刻 20 にもう 1 文字が入力されるため、結果として画面には合計 3 文字が残ることになります。

解法の手順

この問題を解くために、以下の手順に従います。

s := 1
n := 配列 A のサイズ
i := 1 で初期化し、i < n の間、i を 1 ずつ増やしながら繰り返す:
    もし (A[i] - A[i - 1]) <= c ならば:
        s を 1 増やす
    そうでなければ:
        s := 1
s を返す

このアルゴリズムの考え方は非常にシンプルです。隣接する入力時刻の差が c 秒以内であればカウントを継続し、c 秒を超えると画面がクリアされてカウントが 1 に戻ります。配列を一度走査するだけで答えが求まるため、計算量は O(n)、空間計算量は O(1) と非常に効率的です。

実装例

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

#include <bits/stdc++.h>
using namespace std;

int solve(vector<int> A, int c) {
    int s = 1;
    int n = A.size();
    for (int i = 1; i < n; i++) {
        if ((A[i] - A[i - 1]) <= c) {
            s++;
        } else {
            s = 1;
        }
    }
    return s;
}
int main() {
    vector<int> A = { 1, 3, 8, 14, 19, 20 };
    int c = 5;
    cout << solve(A, c) << endl;
}

入力

{ 1, 3, 8, 14, 19, 20 }, 5

出力

3
  1. C++でドミノとトロミノを使って2×nのボードを埋める配置の数を数えるプログラム

    ここでは、ドミノ(2×1の長方形)とトロミノ(L字型)という2種類のピースを扱います。どちらのピースも、下図のように回転させて使用することができます。整数 n が与えられたとき、これらのピースを組み合わせて 2×n のボードを余りなく完全に埋める配置が何通りあるかを求めます。タイル張りのルールでは、すべてのマスが必ずいずれかのピースで覆われている必要があります。例えば入力が 3 の場合、出力は 5 になります。実際の配置例は以下の通りです(異なる文字は異なるピースを表しています)。[XYZ XXZ XYY XXY XYY][XYZ YYZ XZZ XYY XXY]解法のアプローチ:動的計画法こ

  2. 【C++】バイナリ行列をすべて0に変換するための最小操作回数を求めるプログラム

    問題概要0と1のみから構成されるバイナリ行列が与えられます。使用できる操作は「任意の1つのセルを選び、そのセル自身と上下左右の隣接するセル(存在する場合のみ)をすべて反転(0→1、1→0)する」というものです。この操作を繰り返して行列の全要素を0にするために必要な最小操作回数を求めてください。どのように操作してもすべて0にできない場合は -1 を返します。入力例{{0, 0}, {1, 0}}これは次のような2×2の行列です。0010出力3この場合、必要な操作回数は3回となります。解法のアプローチこの問題は、行列の状態をビットマスク(整数)として表現し、幅優先探索(BFS)で最短操作回数を求め