クライアントからの着信時に処理すべき注文数をカウントするC++プログラム
3つの整数 n、m、z があるとします。あるオフィスでは、n 分ごとにクライアントから電話がかかってきて、m 分ごとに新しい注文(配達)が届きます。オフィスは合計 z 分間営業しています。
ここで求めたいのは、クライアントからの電話がかかった時点で未処理の注文が残らないようにするために、最低限いくつの注文を処理する必要があるかという数です。なお、注文を受け取る作業も、クライアントとの通話も、それぞれちょうど1分かかるものとします。
例えば、入力が n = 1、m = 2、z = 5 の場合、出力は 2 になります。これは、2分目と4分目に届いた注文を処理すればよいからです。
解法の考え方
この問題を解く鍵となるのは最小公倍数(LCM)です。クライアントからの電話と注文の到着が同時に重なるのは、n と m の両方の倍数である時刻、つまり lcm(n, m) 分ごとに発生します。
したがって、営業時間 z 分の中で注文を処理すべき回数は、次の式で求められます。
return z / ((n * m) / (nとmの最大公約数));
ここで (n * m) / gcd(n, m) は n と m の最小公倍数を表しています。最大公約数(gcd)を使うことで、オーバーフローを避けながら効率的に LCM を計算できます。
実装例
理解を深めるために、以下のC++による実装を見てみましょう。
#include <bits/stdc++.h>
using namespace std;
int solve(int n, int m, int z){
return z / ((n * m) / __gcd(n, m));
}
int main(){
int n = 1;
int m = 2;
int z = 5;
cout << solve(n, m, z) << endl;
}入力
1, 2, 5
出力
2
このように、最大公約数を利用した最小公倍数の計算により、営業時間内に処理が必要な注文の最小数を O(log(min(n, m))) の計算量で効率的に求めることができます。
-
ロボットが最終位置に到達するまでの最小ステップ数を求めるC++プログラム
2つの座標 (x1, y1) と (x2, y2) があるとします。ロボットは現在点 (x1, y1) にいて、点 (x2, y2) へ移動したいと考えています。ロボットは1ステップごとに、周囲8方向(上下左右と斜め)の隣接するマスのいずれかに移動することができます。このとき、最終位置に到達するために必要な最小ステップ数を求めます。 例えば、入力が x1 = 3; y1 = 4; x2 = 6; y2 = 1; の場合、出力は 3 になります。その様子は以下の図の通りです。 解き方 この問題を解くには、次のステップに従います。 return max(|x2 - x1|, |y2 - y1|
-
C++でアルファベット順に並ぶ部分文字列の個数を求める方法
問題の概要長さ n の文字列を考えます。この文字列には大文字のアルファベットのみが含まれており、その中から「各文字がアルファベット順(A→B→C…)に連続して並んでいる」部分文字列の個数を求めます。なお、部分文字列の最小サイズは 2 とします。例えば、文字列が「REFJHLMNBV」の場合、条件を満たす部分文字列は「EF」と「MN」の 2 つとなります。解決のための手順この問題は、文字列を一度走査するだけで効率的に解くことができます。手順は以下の通りです。隣り合う文字同士を比較し、str[i] + 1 が str[i + 1] と等しい(=文字コード上で1つずつ連続している)かどうかを確認しま