C++で各ステーションの最終的な放射強度を計算する方法
直線上にN個のステーションが並んでおり、それぞれが非負の放射出力を持っていると仮定します。各ステーションは、一定のルールに従って隣接するステーションの放射強度を高めます。
例えば、ステーションiの放射強度がRであるとき、このステーションは左側では(i-1)番目のステーションの放射強度を「R-1」だけ、(i-2)番目のステーションを「R-2」だけ増やします。同様に右側でも、(i+1)番目のステーションに「R-1」、(i+2)番目のステーションに「R-2」を加えます。距離が1つ離れるごとに寄与は1ずつ減少し、その値が0以下になった時点で影響は及ばないものとします。
具体例
配列 Arr = [1, 2, 3] の場合を考えてみましょう。
- ステーション0(強度1): 隣のステーション1への寄与は R-1 = 0 となるため影響なし
- ステーション1(強度2): ステーション0とステーション2にそれぞれ +1
- ステーション2(強度3): ステーション1に +2、ステーション0に +1
したがって、最終的な放射強度は次のように計算されます。
[1 + (2 - 1) + (3 - 2), 2 + (1 - 1) + (3 - 1), 3 + (2 - 1)] = [3, 4, 4]
アルゴリズムの考え方
発想はシンプルです。各ステーションiを基準として、上記のルールに従い左右の隣接ステーションへ効果を加算していき、有効な寄与が負になる直前まで処理を続けます。
C++での実装例
#include <iostream>
#include <vector>
using namespace std;
vector<int> findFinalRadiation(const vector<int>& arr) {
int n = arr.size();
vector<int> result(n, 0);
for (int i = 0; i < n; i++) {
result[i] += arr[i];
// 左方向への伝播
int power = arr[i] - 1;
for (int j = i - 1; j >= 0 && power > 0; j--) {
result[j] += power;
power--;
}
// 右方向への伝播
power = arr[i] - 1;
for (int j = i + 1; j < n && power > 0; j++) {
result[j] += power;
power--;
}
}
return result;
}
int main() {
vector<int> arr = {1, 2, 3};
vector<int> result = findFinalRadiation(arr);
cout << "最終的な放射強度 : ";
for (int r : result)
cout << r << " ";
return 0;
}出力
最終的な放射強度 : 3 4 4
計算量
時間計算量はO(N²)、空間計算量はO(N)となります。ステーション数Nが大きくなるほど処理に時間がかかるため、累積和や差分の考え方を取り入れることで、より効率的に高速化することも可能です。
-
C++で2次元デカルト座標点をすべて接続する最小コストを求めるプログラム
問題の概要2次元デカルト座標上の点のリスト(x, y)が与えられたとします。点(x0, y0)と(x1, y1)を接続するときのコストは、|x0 − x1| + |y0 − y1|(マンハッタン距離)で表されます。任意の数の点を接続できる場合、すべての点がひとつのパスでつながるようにするために必要な最小コストを求めます。例えば、入力が points = [[0, 0], [0, 2], [0, -2], [2, 0], [-2, 0], [2, 3], [2, -3]] の場合を考えてみましょう。このとき出力は 14 になります。その理由は以下の通りです。(0, 0) から (0, 2)、(0
-
C++プログラムにおける二分探索(バイナリサーチ)の基本と実装
二分探索(バイナリサーチ)とは二分探索は「半区間探索」「対数探索」「バイナリチョップ」とも呼ばれる検索アルゴリズムで、ソート済みの配列の中から目的の値が存在する位置を効率的に見つけ出します。基本的な仕組みは非常にシンプルです。まず、探したい値(ターゲット値)を配列の中央の要素と比較します。一致しなかった場合は、ターゲット値が存在し得ない半分を丸ごと排除し、残りの半分に対して同様の比較を繰り返します。この「中央との比較」と「範囲の絞り込み」を続け、ターゲット値が見つかるか、検索範囲が空になる(=配列にその値が存在しない)かのどちらかで処理が終了します。アイデア自体は簡単ですが、正しく実装するには