Skip to content

Commit 51acccf

Browse files
authored
Merge pull request #69 from myoshi2891/dev/macbook_pro
atcoder B12 - Equation 二分探索
2 parents e0224ae + 3e96d0a commit 51acccf

6 files changed

Lines changed: 623 additions & 0 deletions

File tree

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// 以下は、Go言語(Golang)を用いて方程式 $x^3 + x = N$ を満たす正の実数 $x$ を **二分探索で求めるコード**です。
2+
// **型を明示**し、**処理時間とメモリ消費量**にも配慮しています。
3+
4+
// ## ✅ 解法:二分探索
5+
6+
// * 関数 $f(x) = x^3 + x$ は **単調増加関数**なので、**二分探索**が有効。
7+
// * 解の誤差が **絶対または相対誤差 0.001 以下**になるまで探索。
8+
// * Go の `float64` を使い、収束精度は十分。
9+
10+
// ## ✅ Go 実装コード(型明示)
11+
package main
12+
13+
import (
14+
"bufio"
15+
"fmt"
16+
"math"
17+
"os"
18+
"strconv"
19+
"strings"
20+
)
21+
22+
func main() {
23+
// 標準入力読み込み
24+
reader := bufio.NewReader(os.Stdin)
25+
line, _ := reader.ReadString('\n')
26+
NStr := strings.TrimSpace(line)
27+
N, err := strconv.ParseFloat(NStr, 64)
28+
if err != nil {
29+
panic(err)
30+
}
31+
32+
// 型: float64
33+
var low float64 = 0.0
34+
var high float64 = math.Max(1.0, N)
35+
var mid float64
36+
37+
for i := 0; i < 100; i++ {
38+
mid = (low + high) / 2
39+
f := mid*mid*mid + mid // f(x) = x^3 + x
40+
if f > N {
41+
high = mid
42+
} else {
43+
low = mid
44+
}
45+
}
46+
47+
// 小数点6桁まで出力
48+
fmt.Printf("%.6f\n", mid)
49+
}
50+
51+
// ## ✅ 使用例
52+
53+
// ### 入力:
54+
55+
// ```
56+
// 2
57+
// ```
58+
59+
// ### 出力:
60+
61+
// ```
62+
// 1.000000
63+
// ```
64+
65+
// ---
66+
67+
// ## ✅ 型の明示について
68+
69+
// | 変数名 | 型 | 説明 |
70+
// | ------ | --------- | --------------- |
71+
// | `N` | `float64` | 入力値(正の実数) |
72+
// | `low` | `float64` | 二分探索の下限 |
73+
// | `high` | `float64` | 二分探索の上限 |
74+
// | `mid` | `float64` | 探索中間値(出力対象) |
75+
// | `f` | `float64` | 計算された関数値 $f(x)$ |
76+
77+
// ---
78+
79+
// ## ✅ 処理時間・メモリ消費量の目安(Go)
80+
81+
// | 指標 | 内容 |
82+
// | ------ | ------------------------- |
83+
// | 時間計算量 | $O(\log N)$(最大100ステップ) |
84+
// | 実行時間 | 約 1〜2 ms(Go 1.20以降の標準ビルド) |
85+
// | メモリ使用量 | 数MB(浮動小数 + 入出力バッファのみ) |
86+
87+
// ---
88+
89+
// ## ✅ なぜ100回ループするのか?
90+
91+
// * $2^{-20} ≈ 10^{-6}$ なので、誤差 $\leq 0.001$ にするには20〜30回で十分。
92+
// * **100回のループ**にすることで安全に収束するようにしている。
93+
94+
// ---
95+
96+
// ## ✅ 簡易図解:探索の流れ
97+
98+
// ```
99+
// f(x) = x^3 + x の単調増加
100+
101+
// 探索範囲:
102+
// [low]----------------[high]
103+
// 0.0 N
104+
105+
// 繰り返しで収束:
106+
// [0.0 .......... mid .......... N]
107+
// ↓
108+
// [0.0 ...... mid ......]
109+
// ↓
110+
// [mid - ε ... mid + ε] ≈ 解
111+
// ```
112+
113+
// ---
114+
115+
// Goでは `float64` の精度で十分な誤差範囲(0.001)に収束できます。
116+
// ご希望があれば、誤差制御をループ回数ではなく **相対誤差判定で停止**させる改良も可能です。
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// 以下は、与えられた方程式 $x^3 + x = N$ を満たす正の実数 $x$ を **2分探索**で求める JavaScript コードです。
2+
// `fs` モジュールを使用して標準入力から値を読み取り、解の精度は絶対誤差または相対誤差が 0.001 以下になるまで繰り返します。
3+
4+
// ### ✅ 解法:二分探索(精度重視)
5+
6+
// * 解となる $x$ は単調増加な関数 $f(x) = x^3 + x$ によって定まる。
7+
// * よって、1 ≦ N ≦ 100000 の範囲で、右端を十分大きな値(例:N)にして探索。
8+
9+
// ### ✅ JavaScript 実装(`fs`使用)
10+
11+
const fs = require("fs");
12+
13+
const input = fs.readFileSync("/dev/stdin", "utf8").trim();
14+
const N = parseFloat(input);
15+
16+
// x^3 + x = N を満たす x を求める(絶対/相対誤差 0.001 以下)
17+
let low = 0.0;
18+
let high = Math.max(1, N); // N=1のときに0〜1の範囲に解があることを保証
19+
let mid;
20+
21+
for (let i = 0; i < 100; i++) { // 高速に収束するため100回で十分
22+
mid = (low + high) / 2;
23+
const f = mid ** 3 + mid;
24+
if (f > N) {
25+
high = mid;
26+
} else {
27+
low = mid;
28+
}
29+
}
30+
31+
console.log(mid.toFixed(6));
32+
33+
// ### ✅ 処理時間・メモリ消費量
34+
35+
// * **計算量**:O(log₂(N)) ≒ 100ステップ未満で収束。
36+
// * **メモリ使用**:10MB 未満(fs + 数値計算のみ)
37+
// * **実行時間**:平均 2〜5ms(Node.js v18+)
38+
39+
// ---
40+
41+
// ### ✅ 入力例の動作確認
42+
43+
// #### 入力:
44+
45+
// ```
46+
// 2
47+
// ```
48+
49+
// #### 出力:
50+
51+
// ```
52+
// 1.000000
53+
// ```
54+
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<!-- 以下は、PHP を用いて方程式 $x^3 + x = N$ を満たす正の実数 $x$ を求めるプログラムです。
2+
**型を明示的に記述しつつ、処理時間およびメモリ使用量にも配慮**しています。
3+
4+
## ✅ 解法方針:二分探索(Binary Search)
5+
6+
* $f(x) = x^3 + x$ は単調増加 ⇒ 二分探索で一意に解を求められる。
7+
* 精度は **絶対誤差または相対誤差 ≤ 0.001** で十分。
8+
* 反復回数を固定(例:100回)とすることで、誤差 $\leq 10^{-6}$ を保証。
9+
10+
## ✅ PHP 実装(型付きコメント付き)
11+
<?php
12+
declare(strict_types=1);
13+
14+
// 入力読み込み
15+
$input = trim(fgets(STDIN));
16+
$N = floatval($input);
17+
18+
// 初期範囲の設定(型明示: float)
19+
$low = 0.0;
20+
$high = max(1.0, $N);
21+
$mid = 0.0;
22+
23+
// 二分探索:誤差 0.001 以下まで収束
24+
for ($i = 0; $i < 100; $i++) {
25+
$mid = ($low + $high) / 2.0;
26+
$f = $mid * $mid * $mid + $mid; // f(x) = x^3 + x
27+
28+
if ($f > $N) {
29+
$high = $mid;
30+
} else {
31+
$low = $mid;
32+
}
33+
}
34+
35+
// 結果出力(小数第6位まで)
36+
printf("%.6f\n", $mid);
37+
38+
// ## ✅ 入出力例
39+
40+
// ### 入力:
41+
42+
// ```
43+
// 2
44+
// ```
45+
46+
// ### 出力:
47+
48+
// ```
49+
// 1.000000
50+
// ```
51+
52+
// ---
53+
54+
// ## ✅ 処理時間・メモリ消費量(目安)
55+
56+
// | 指標 | 内容 |
57+
// | ------ | ---------------------- |
58+
// | 時間計算量 | $O(\log N)$(最大100ステップ) |
59+
// | 実行時間 | 約 1~3 ms(PHP 8.x CLI) |
60+
// | メモリ使用量 | 数 MB 程度(浮動小数とループのみ) |
61+
62+
// ---
63+
64+
// ## ✅ なぜ100回ループするのか?
65+
66+
// * 各ステップで範囲は半分になる(二分探索)。
67+
// * $2^{-20} ≈ 10^{-6}$ ⇒ **20~30回で十分**。
68+
// * **100回回せば誤差 0.001 以下が保証**される。
69+
70+
// ---
71+
72+
// ## ✅ 型の明示(PHP ではコメントベース)
73+
74+
// PHP 8 では以下のような明示が可能:
75+
76+
// ```php
77+
// /** @var float $low */
78+
// /** @var float $high */
79+
// /** @var float $mid */
80+
// ```
81+
82+
// ---
83+
84+
// ## ✅ グラフのイメージ(探索)
85+
86+
// ```
87+
// y = x^3 + x のグラフ
88+
89+
// y
90+
// ^
91+
// | ●
92+
// | ●
93+
// | ●
94+
// | ●
95+
// | ●
96+
// | ●
97+
// |●
98+
// +----------------------------→ x
99+
100+
// 探索範囲が収束:
101+
// [0 .............. N]
102+
// [0 ....... mid]
103+
// [mid ... high]
104+
// ︙
105+
// [1.0000 ± ε]
106+
// ```
107+
108+
// ---
109+
110+
// ご希望があれば、BCMath による任意精度演算対応や、PHPUnit を使ったテストコードの追加も可能です。
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# 以下は、与えられた方程式 $x^3 + x = N$ を満たす正の実数 $x$ を **Python** で求める実装です。
2+
# **型指定付き**で記述し、**処理時間・メモリ使用量**に配慮しています。
3+
4+
# ---
5+
6+
# ## ✅ 解法概要:二分探索
7+
8+
# * 関数 $f(x) = x^3 + x$ は単調増加なので、2分探索が有効。
9+
# * $x \in (0, N)$ の範囲で探索し、**相対誤差 or 絶対誤差 ≤ 0.001** になるまで繰り返します。
10+
11+
# ---
12+
13+
# ## ✅ Python 実装(型付き)
14+
import sys
15+
# from typing import Tuple
16+
17+
def solve() -> None:
18+
input_str: str = sys.stdin.read().strip()
19+
N: float = float(input_str)
20+
21+
low: float = 0.0
22+
high: float = max(1.0, N)
23+
mid: float = 0.0
24+
25+
for _ in range(100):
26+
mid = (low + high) / 2
27+
f: float = mid**3 + mid
28+
if f > N:
29+
high = mid
30+
else:
31+
low = mid
32+
33+
print(f"{mid:.6f}")
34+
35+
if __name__ == "__main__":
36+
solve()
37+
# ```
38+
39+
# ---
40+
41+
# ## ✅ 使用例
42+
43+
# ### 入力:
44+
45+
# ```
46+
# 2
47+
# ```
48+
49+
# ### 出力:
50+
51+
# ```
52+
# 1.000000
53+
# ```
54+
55+
# ---
56+
57+
# ## ✅ 処理時間・メモリ使用量の目安
58+
59+
# | 指標 | 内容 |
60+
# | ---------- | ----------------------- |
61+
# | **時間計算量** | $O(\log N)$(収束まで100回以下) |
62+
# | **実行時間** | 約 1〜3 ms(CPython 3.8+) |
63+
# | **メモリ使用量** | 約 10〜20MB(標準ライブラリ+浮動小数) |
64+
65+
# ---
66+
67+
# ## ✅ 解説図(簡易)
68+
69+
# ```text
70+
# 探索範囲:
71+
# ┌──────────────┐
72+
# low│ │high
73+
# 0.0 N
74+
75+
# 収束イメージ:
76+
# 1回目: [0 ............. N]
77+
# 2回目: [0 ......... mid]
78+
# 3回目: [mid .. high]
79+
# ...
80+
# 最終: [x - ε .. x + ε]
81+
# ```
82+
83+
# ---
84+
85+
# ## ✅ なぜ 100 回で十分か?
86+
87+
# * 二分探索により探索幅が $\frac{1}{2^n}$ に。
88+
# * 精度が $10^{-6}$ 必要なら $n ≈ 20$ 回で十分。
89+
# * 安全に **100回**繰り返すことで収束を保証。
90+
91+
# ---
92+
93+
# ご希望があれば、NumPy や decimal ライブラリを用いた高精度バージョンも提供可能です。

0 commit comments

Comments
 (0)