C/C++で配列の全要素の積をnで割った余りを求めるプログラム
配列乗算の問題では、与えられた配列の全要素の積を計算し、その積を指定された数値nで割った余りを求めます。具体的な例を使って見ていきましょう。
入力: arr[] = { 12, 35, 69, 74, 165, 54 }
N = 47
出力: 14
解説
配列が {12, 35, 69, 74, 165, 54} の場合、全要素の積は次のように計算されます。
(12 × 35 × 69 × 74 × 165 × 54) = 19107673200
この積を47で割ると、余りは14になります。これが出力として期待される値です。
素朴なアプローチの課題
最も単純な考え方は、すべての要素を先に掛け合わせてからnで剰余を取ることです。しかし、このアプローチには重大な欠点があります。配列の要素数が多かったり、各要素の値が大きかったりすると、積が符号なし64ビット整数型の上限(264)を超えてしまい、オーバーフローによって誤った結果が返される可能性があるのです。
解決策:各ステップで剰余を取る
この問題は、剰余演算の基本的な性質を利用することで回避できます。
(a × b) % n = ((a % n) × (b % n)) % n
つまり、各要素を掛け合わせるたびにnの剰余を計算すれば、中間結果が常にn未満に保たれるため、巨大な積を実際に計算することなく、最終的な余りを正確に求めることができます。
アルゴリズムの手順
- 結果を格納する変数
mulを 1 で初期化します。 - 配列の各要素に対して、
mul = (mul × (arr[i] % n)) % nを実行します。 - すべての要素を処理した後の
mulの値が、求める余りとなります。
C/C++での実装例
#include <stdio.h>
int main() {
int arr[] = { 12, 35, 69, 74, 165, 54 };
int len = 6;
int n = 47;
int mul = 1;
for (int i = 0; i < len; i++)
mul = (mul * (arr[i] % n)) % n;
printf("余りは %d です\n", mul);
return 0;
}
出力
余りは 14 です
計算量
- 時間計算量: O(L)(L は配列の長さ)― 各要素を一度だけ処理すればよいため、非常に効率的です。
- 空間計算量: O(1) ― 追加で必要なメモリは定数個の変数のみです。
このように、逐次的に剰余を取る手法を用いれば、積がどれほど大きな値になってもオーバーフローを気にせず、安全かつ効率的に余りを計算できます。競技プログラミングなどでも頻出するテクニックなので、ぜひ覚えておきましょう。
-
C++で平行四辺形の面積を求めるプログラムの作成方法
この記事では、平行四辺形の底辺と高さを表す2つの値が与えられたとき、C++を使ってその面積を求めるプログラムを作成する方法を解説します。 平行四辺形とは? 平行四辺形とは、4つの辺からなる閉じた図形であり、向かい合う2組の辺がそれぞれ長さが等しく、互いに平行になっている四角形のことです。 問題を理解するための具体例 入力 B = 20, H = 15 出力 300 説明 平行四辺形の面積 = 底辺 × 高さ = 20 × 15 = 300 解決アプローチ この問題を解くには、平行四辺形の面積を求める幾何学の公式を使用します。 面積 = 底辺 × 高さ つまり、与えられた底辺と高さを掛け合わせ
-
【Python】配列の全要素の積をnで割った余りを求めるプログラムの書き方
本記事では、以下の問題に対する解決策について詳しく解説します。問題文複数の数値からなる配列と整数 n が与えられたとき、配列内のすべての要素を掛け合わせた結果を n で割った余りを出力する必要があります。アプローチまず、arr[i] % n のように各要素の余りを個別に計算します。次に、その余りを現在の結果に掛け合わせます。掛け算を行うたびに再度剰余演算を適用することで、オーバーフローを回避できます。この手法は、モジュラー算術(合同式)の分配則に基づいています。( a * b) % c = ( ( a % c ) * ( b % c ) ) % c実装例def findremainder(ar