C++で数がプロス数(Proth数)かどうかを判定するプログラム
ある正の整数「n」が与えられたとき、その数がプロス数(Proth数)であるかどうかを判定し、結果を出力するのが本記事のテーマです。
プロス数とは?
プロス数とは、次の形で表される数のことです。
N = k × 2n + 1
ここで、n は正の整数、k は奇数の正の整数です。
最初のいくつかのプロス数は以下の通りです。
3, 5, 9, 13, 17, 25, 33, 41, 49, 57, 65, 81, 97.......
入力
number: 17
出力
its a proth number(プロス数です)
入力
number: 18
出力
its not a proth number(プロス数ではありません)
プログラムのアプローチ
判定したい数を入力として受け取る
プロス数の定義式に基づき、その数がプロス数かどうかを判定する
条件が成立すれば「プロス数である」と出力する
条件が成立しなければ「プロス数ではない」と出力する
アルゴリズム
ステップ1→ 2のべき乗かどうかを判定する関数を宣言する
bool isPower(int num)
return (num && !(num & (num - 1)))
ステップ2→ 数がプロス数かどうかを判定する関数を宣言する
bool isProth(int num)
int k = 1 を宣言
While (k < (num / k))
IF (num % k == 0)
IF (isPower(num / k))
return true
End
End
k = k + 2 を設定
End
return false
ステップ3→ main() 内での処理
int num = 17 を宣言
IF (isProth(num - 1))
"its a proth number" を出力
Else
"its not a proth number" を出力
終了
コード例
#include <bits/stdc++.h>
using namespace std;
// 2のべき乗かどうかを判定する関数
bool isPower(int num){
return (num && !(num & (num - 1)));
}
// 数がプロス数かどうかを判定する関数
bool isProth(int num){
int k = 1;
while (k < (num / k)){
if (num % k == 0){
if (isPower(num / k))
return true;
}
k = k + 2;
}
return false;
}
int main(){
int num = 17;
if (isProth(num - 1))
cout << "its a proth number";
else
cout << "its not a proth number";
return 0;
}
コードのポイント
isPower() 関数では、ビット演算を利用して 2 のべき乗を効率的に判定しています。「num と num − 1 の論理積(AND)が 0 になるなら、num は 2 のべき乗である」という性質を使った定番テクニックです。
また、main() 内で isProth(num - 1) を呼び出しているのは、「num がプロス数である ⟺ num − 1 が k × 2n の形に分解できる」という性質を利用するためです。num − 1 を奇数 k と 2 のべき乗の積に分解できれば、num はプロス数だと判定できます。
出力
上記のコードを実行すると、次の出力が得られます。
its a proth number
これは、17 がプロス数(17 = 1 × 24 + 1)であることを示しています。
-
C++で二分木が高さバランスされているかどうかを判定するプログラム
C++で二分木の高さバランスを判定する方法 二分木が与えられたとき、その木が「高さバランス」されているかどうかを判定する必要があります。 高さバランスされた木とは、すべてのノードにおいて、左部分木の高さと右部分木の高さの絶対差が0または1以内に収まっている木のことです。 例えば、以下のような二分木が入力として与えられたとします。 この場合、出力は True(バランスされている)となります。 解決のアプローチ この問題を解くには、DFS(深さ優先探索)を利用して各ノードの部分木の高さを計算し、その差を確認します。手順は以下の通りです。 dfs() 関数を定義し、ノードを引数として受け取ります
-
C++で有向グラフの強連結成分を検出するプログラムの作成方法
有向グラフにおいて、ある成分内の任意の頂点ペア同士の間に経路が存在するとき、その成分は「強く接続されている(強連結)」といいます。このような成分のことを強連結成分(SCC: Strongly Connected Components)と呼びます。この問題を解くには、まずDFS(深さ優先探索)を使って各頂点の完了時刻(finish time)を求めます。次にグラフを転置し、完了時刻をもとに頂点を降順に並べる(トポロジカルソート)ことで、強連結成分を一つずつ取り出します。これは有名なKosarajuのアルゴリズムに基づいた手法です。入力: グラフの隣接行列001101000001000000010