兩堆桃子 (a, b),雙方輪流操作,每次可:
這正是經典的 威佐夫博弈,又稱「取石子遊戲」變體。
設兩堆數量為 (x, y),且 x ≤ y。定義 冷位置:先手必敗的局面。所有冷位置由以下公式生成:
k = 0, 1, 2, ...
a_k = floor(k * φ)
b_k = floor(k * φ²) = a_k + k
其中 φ = (1 + √5) / 2 ≈ 1.618033988749895 (黃金分割比)
前幾對冷位置:
(0,0), (1,2), (3,5), (4,7), (6,10), (8,13), (9,15), (11,18), (12,20), (14,23)...
給定初始 (a, b),設 x = min(a,b), y = max(a,b),d = y - x。
若 x == floor(d * φ),則為冷位置,**先手敗 (輸出 0)**;否則**先手勝 (輸出 1)**。
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
const double PHI = (1.0 + sqrt(5.0)) / 2.0;
int m; cin >> m;
while (m--) {
long long a, b; cin >> a >> b;
if (a > b) swap(a, b);
long long d = b - a;
long long ak = (long long)(d * PHI);
cout << (a == ak ? 0 : 1) << '\n';
}
return 0;
}
| 輸入 (a,b) | d=b-a | floor(d*φ) | a==? | 結果 |
|---|---|---|---|---|
| 6 10 | 4 | 6 | 是 | 0 (敗) |
| 2 1 | 1 | 1 | 否 (x=1, ak=1? 1==1 是! 但注意 x=min=1, ak=1 => 0? 樣例輸出0。重新算:a=1,b=2,d=1,ak=1,x=1 => 0。正確) | 0 |
| 8 4 | 4 | 6 | 否 (x=4) | 1 (勝) |
| 4 7 | 3 | 4 | 是 | 0 |
完全匹配樣例輸出。
雙精度 `double` 52 位尾數,精確表示 10^15 以內整數。對於 10^18 需用 `long double` (80位) 或整數運算避免精度誤差:
// 整數判定避免浮點誤差
// x == floor(d * φ) <=> x ≤ d*φ < x+1
// 平方消去根號:φ = (1+√5)/2
// 等價於判斷 (2*x - d)^2 < 5*d^2 且 (2*x - d + 2)^2 > 5*d^2
// 使用 __int128 防溢出