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

床全体を照らすのに必要なランプの最小数を求めるC++プログラム

n行m列のグリッドに区切られた床があるとします。この床全体をランプで照らすことを考えます。ランプは2つのセル(マス)の境界に設置でき、縦方向の境界に置いた場合はその左右の2つのセルを、横方向の境界に置いた場合はその前後の2つのセルを照らします。与えられたnとmに対して、床全体を照らすために必要なランプの最小個数を求めるのがこの問題です。

例えば、入力が n = 5、m = 3 の場合、出力は 8 になります。

解法のアプローチ

この問題は非常にシンプルな計算式で解くことができます。1つのランプが2つのセルを同時に照らせるため、必要なランプ数はセルの総数(n × m)を2で割った値になります。ただし、セルの総数が奇数の場合は切り上げが必要です。そこで、次の式を使用します。

res := (n * m + 1) / 2
return res

(n × m + 1) を 2 で割ることで、セルの総数が奇数の場合でも自動的に切り上げ処理が行われ、正しい最小ランプ数を求められます。

実装例

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

#include <bits/stdc++.h>
using namespace std;
#define N 100
int solve(int n, int m) {
   int res = (n * m + 1) / 2;
   return res;
}
int main() {
   int n = 5, m = 3;
   cout<< solve(n, m);
   return 0;
}

入力

5, 3

出力

8

計算例の確認

n = 5、m = 3 の場合、セルの総数は 5 × 3 = 15 です。このとき (15 + 1) / 2 = 8 となるため、答えは 8 になります。このように、整数除算の特性を活かしたシンプルな式で効率的に解答を得ることができます。

  1. C++で最短スーパーストリング(最短共通超文字列)を求めるアルゴリズム

    問題概要文字列の配列 A が与えられたとき、A に含まれるすべての文字列を部分文字列として持つ、最も短い文字列(スーパーストリング)を1つ求めることを考えます。ただし、A 内のどの文字列も、他の文字列の部分文字列ではないものと仮定できます。たとえば、入力が [dbsh, dsbbhs, hdsb, ssdb, bshdbsd] の場合、出力は hdsbbhssdbshdbsd となります。この問題は、文字列同士の重なり(オーバーラップ)を辺のコストとみなすことで、巡回セールスマン問題(TSP)とよく似た構造になり、ビットDP(動的計画法)を用いて効率的に解くことができます。アルゴリズムの考え方

  2. C++で数値に最も近い回文数を求めるアルゴリズムと実装例

    問題の概要 ある数値 n が与えられたとき、それに最も近い回文数(前から読んでも後ろから読んでも同じ並びになる数)を求める問題を考えます。「近さ」は絶対差で評価し、n より小さい回文でも大きい回文でも、差がより小さい方を採用します。 たとえば入力が 145 の場合を考えてみましょう。 下側の回文 141 との差は 4、上側の回文 151 との差は 6 です。差がより小さいのは 141 なので、答えは 141 になります。 解法の方針 すべての数を順番に調べて回文かどうか判定する方法は非効率です。そこで、「最も近い回文となり得る候補」だけを少数ピックアップして比較します。候補となるのは次のパタ