C++で集合の反射関係の数を求める方法
この記事では、C++を使って集合上に定義できる反射関係(reflexive relation)の総数を求める方法について解説します。問題設定としては、整数 n が与えられたとき、n 個の自然数からなる集合上に存在する反射関係の個数を求めるというものです。
反射関係とは
集合 A 上の関係 R が反射的であるとは、「A に属するすべての要素 a に対して、順序対 (a, a) が必ず R に含まれる」という条件を満たすことを意味します。数式で表すと次のようになります。
(a, a) ∈ R (∀ a ∈ A)
具体的な入出力の例を見てみましょう。
入力 : x = 1
出力 : 1
説明 : 集合 = { 1 } のとき、A × A 上の反射関係 :
{ { 1 } }
入力 : x = 2
出力 : 4
説明 : 集合 = { 1, 2 } のとき、A × A 上の反射関係 :
{ ( 1, 1 ), ( 2, 2 ) }
{ ( 1, 1 ), ( 2, 2 ), ( 1, 2 ) }
{ ( 1, 1 ), ( 2, 2 ), ( 1, 2 ), ( 2, 1 ) }
{ ( 1, 1 ), ( 2, 2 ), ( 2, 1 ) }
解法の考え方
n 要素の集合上の反射関係の数は、次の公式で求められます。
2n²−n
この公式が成り立つ理由は以下の通りです。反射関係では、対角成分にあたる n 個の順序対 (a, a) は必ず含まれていなければなりません。一方、それ以外の n² − n 個の非対角ペアについては、それぞれ「関係に含めるかどうか」を自由に選ぶことができます。各ペアに2通りの選択肢があるため、全体で 2n²−n 通りの反射関係が存在することになります。

C++での実装例
#include <iostream>
using namespace std;
int countReflexive(int n){
int ans = 1 << (n*n - n);
return ans;
}
int main(){
int n ;
cin >> n ; // 標準入力から n を受け取る
int result = countReflexive(n); // 反射関係の数を計算する関数を呼び出し
cout << \"Number of reflexive relations on set: \" << result ; // 結果を出力
return 0;
}
出力結果
Number of reflexive relations on set: 1
プログラムの解説
このプログラムの流れは非常にシンプルです。ユーザーから n を入力として受け取り、公式 2n²−n を計算しているだけです。2 のべき乗の計算にはビット左シフト演算子「<<」を使用しており、これにより高速に値を求められます。時間計算量は O(1) です。ただし、int 型で表現できる範囲には限りがあるため、n が大きくなるとオーバーフローを起こす点には注意が必要です。より大きな n を扱いたい場合は、long long 型や多倍長整数型の利用を検討するとよいでしょう。
まとめ
この記事では、集合上の反射関係の数を求める問題を取り上げました。数学者によって導き出された公式 2n²−n を利用することで、複雑な全列挙を行わずとも非常にシンプルに答えを計算できることを確認しました。また、C++による実装例を通じて、O(1) の時間計算量で解を得る方法を学びました。同じロジックは C、Java、Python など他の言語でも同様に実装可能です。
-
C++で文字列の部分文字列の総数を求める方法を解説
この記事では、与えられた文字列から作成できる空でない部分文字列の個数を求める方法について解説します。入力 : string = "moon" 出力 : 10 説明 : 部分文字列は m、o、o、n、mo、oo、on、moo、oon、moon の 10 個です。 入力 : string = "yellow" 出力 : 21解法のアプローチ文字列の長さを n とします。上の例からも分かるように、考えられるすべての部分文字列の個数を求めるには、長さ n、(n-1)、(n-2)、(n-3)、……2、1 の部分文字列の個数を順に加算していく必要があります。部分文
-
C++で列車の停車駅の組み合わせ数を求める方法
地点XとYの間にはn個の中間駅があるとします。ここで、「どの2つの停車駅も隣り合わない」という条件のもとで、s個の駅に停車する列車の配置方法が何通りあるかを求める問題を考えてみましょう。この記事では、停車駅の組み合わせ数を求めるためのアプローチを段階的に詳しく解説します。この問題は、本質的には組合せ論の問題であり、s個の停車駅の選び方の総数を求めることになります。 問題を解くアプローチ まず具体例として、中間駅が8個あり、そのうち3個の駅に停車させたい場合を考えてみます。 n = 8, s = 3 このとき、列車が停車できない駅は(n − s)、つまり5個残ることになります。 停車できない