C++で1からNまでの範囲のうちXで割り切れ、かつYでは割り切れない数をカウントする方法
はじめに
整数 N が与えられたとき、1 から N までの範囲に含まれる数のうち、「X で割り切れるが Y では割り切れない」数の個数を求めるのが本記事の目的です。
具体例を見てみましょう。
例1
入力:
N=20 X=5 Y=20
出力:
1からNまでのうちXで割り切れYでは割り切れない数: 2
解説:
5と15のみが5で割り切れ、10では割り切れません。
例2
入力:
N=20 X=4 Y=7
出力:
1からNまでのうちXで割り切れYでは割り切れない数: 5
解説:
4、8、12、16、20 の5つの数は4で割り切れますが、7では割り切れません。
プログラムのアプローチ
- 整数 N を入力として受け取ります。
- 関数 divisibleXY(int x, int y, int n) は、1 から N までの範囲で X で割り切れ、かつ Y では割り切れない数の個数を返します。
- カウント用の変数 count を初期値 0 で宣言します。
- for ループを使って i = 1 から i = n まで順に走査します。
- 各数値 i に対して「i % x == 0 かつ i % y != 0」という条件を判定し、真であれば count をインクリメントします。
- 最後に count を結果として返します。
サンプルコード
#include <bits/stdc++.h>
using namespace std;
int divisibleXY(int x, int y, int n){
int count = 0;
for (int i = 1; i <= n; i++) {
if(i%x==0 && i%y!=0 )
{ count++; }
}
return count;
}
int main(){
int N = 100;
int X=6, Y=8;
cout <<"1からNまでのうちXで割り切れYでは割り切れない数: "<< divisibleXY(X,Y,N);
return 0;
}
出力
上記のコードを実行すると、次の出力が得られます。
1からNまでのうちXで割り切れYでは割り切れない数: 12
補足:より効率的な計算方法
上記の方法は O(N) の時間計算量を持ちますが、数学的な性質を使うと O(1) で求めることも可能です。1 から N までの間で X の倍数の個数は「N / X」(小数点以下切り捨て)、XY の公倍数(最小公倍数 LCM)の倍数の個数は「N / LCM(X, Y)」となります。したがって、答えは次の式で計算できます。
count = (N / X) - (N / lcm(X, Y));
この方法を使えば、N が非常に大きい場合でも高速に答えを求めることができます。
-
C++でバイナリ行列内の1に囲まれた0の個数を数えるアルゴリズム
本記事では、バイナリ行列(0と1のみで構成される行列)の中から、1によって完全に囲まれている0の個数を求めるプログラムについて解説します。具体的には、0と1からなる行列が与えられたとき、行列の外側に到達できない、つまり1に囲まれて閉じ込められている0をすべて見つけ出し、その個数をカウントするのが目的です。アルゴリズムの考え方この問題は「境界からたどり着ける0」と「たどり着けない0」を区別することで解決できます。手順は以下のとおりです。1. 行列の四辺(上端・下端・左端・右端)にある0を起点として、深さ優先探索(DFS)を実行します。2. DFSで到達できた0はすべて1に書き換え、訪問済みとして
-
C++で3で割り切れるが6で割り切れない数nの順列を求める方法
問題の概要ある数nが与えられたとき、その桁を並べ替えた順列の中から「3で割り切れるが、6では割り切れない」数を見つけることを考えます。そのような値を作ることができない場合は、-1を返します。例えば、nが336の場合、答えの候補として363が出力されます。解法の考え方ご存知の通り、6で割り切れる数とは、3と2の両方で割り切れる数のことです。つまり、3で割り切れる偶数は必ず6でも割り切れます。そこで、3で割り切れかつ偶数である数の桁を入れ替えて奇数にすることができれば、その数が求める答えとなります。ここで重要なポイントとして、桁を並べ替えても各位の数字の合計は変わらないため、元の数が3で割り切れれ