立方数ペアの探索 – O(n^(2/3)) 解法を C++ で実装
問題概要
ある整数 n が与えられたとき、n を「2つの立方数の和」として表せる 2 組の異なるペアを見つけるのが本記事のテーマです。具体的には、n = a3 + b3 = c3 + d3 を満たすようなペア (a, b) と (c, d) を求めます。
この種の数は「タクシー数(Taxicab Number)」として知られており、最も有名な例は 1729 = 13 + 123 = 93 + 103(通称:ラマヌジャン数)です。
解法の考え方
重要なポイントは、a、b、c、d のすべてが n1/3 以下の範囲に収まるという点です。そこで、n1/3 以下の数から作られるすべての異なるペア (x, y) を順番に調べ、x3 + y3 が与えられた数 n と一致するものを探します。
一致したペアは、その和の値をキーとしてハッシュテーブル(map)に格納します。そして、同じ和が再び見つかった時点で、保存しておいたペアと現在のペアの両方を出力すればよいのです。組み合わせの総数はおよそ O(n2/3) 個であるため、全体の計算量もこれに比例して抑えられます。
アルゴリズム
getPairs(n): 開始 cube_root := n の立方根 map(キー: int型、値: pair型)を用意 i を 1 から cube_root まで繰り返す j を i+1 から cube_root まで繰り返す sum = i^3 + j^3 を計算 sum が n と等しくなければ、次の反復へスキップ sum が map に既に存在すれば、保存済みペアと (i, j) を出力 存在しなければ、sum をキーとして (i, j) を map に挿入 内側のループ終了 外側のループ終了 終了
C++ 実装例
#include <iostream>
#include <cmath>
#include <map>
using namespace std;
int getPairs(int n){
int cube_root = pow(n, 1.0/3.0);
map<int, pair<int, int> > my_map;
for(int i = 1; i<cube_root; i++){
for(int j = i + 1; j<= cube_root; j++){
int sum = i*i*i + j*j*j;
if(sum != n)
continue;
if(my_map.find(sum) != my_map.end()){
cout << "(" << my_map[sum].first << ", " << my_map[sum].second << ") and (" << i << ", " << j << ")" << endl;
}else{
my_map[sum] = make_pair(i, j);
}
}
}
}
int main() {
int n = 13832;
getPairs(n);
}実行結果
(2, 24) and (18, 20)
この出力は、13832 = 23 + 243 = 183 + 203 という関係が正しく成立していることを示しています。
計算量
- 時間計算量: O(n2/3) ― 立方根以下の数から選ばれるペアの総数に比例します。
- 空間計算量: O(n2/3) ― マップに保存されるエントリの数に依存します。
-
C++で三角形の周囲の長さ(外周)を求める方法
この記事では、三角形の周囲の長さ(外周)とは何か、三角形の種類ごとの周囲の長さの公式、そしてC++でそれらを求めるプログラムの書き方について詳しく解説します。周囲の長さ(Perimeter)とは周囲の長さとは、図形の外側を1周したときの総距離のことです。基本的には、図形を構成するすべての辺の長さを足し合わせたものになります。三角形の周囲の長さ三角形は3つの辺を持つ図形であるため、その周囲の長さは3辺の長さの合計として求められます。公式:周囲の長さ = すべての辺の合計周囲の長さ = x + y + z三角形の周囲の長さを求めるC++プログラムサンプルコード#include <iostre
-
1/1! + 2/2! + 3/3! + …… + n/n! の級数の合計を求めるPythonプログラム
この記事では、与えられた問題を解くための解法とアプローチについて詳しく解説します。 問題文 整数 n が入力として与えられたとき、次の級数の合計を求めます。 1/1! + 2/2! + 3/3! + 4/4! + …… + n/n! ここでは for ループを使用して実装するため、時間計算量は O(n) となります。また、処理効率を高めるポイントとして、階乗の計算を同じループ内で同時に行っている点が挙げられます。 アルゴリズム 以下の手順で級数の合計を求めます。 合計値 res を 0、階乗値 fact を 1 で初期化します。 i を 1 から n まで順に処理し、fact *= i に