威佐夫博弈及其拓展
威佐夫博弈
普通威佐夫博弈:
兩種操作:一、同時在兩堆上取相同的個數。二、在某一堆上取任意個數。(每次取不為0)
a[n]=nα,b[n]=a[n]+n,α=1+52a[n] = n \alpha, b[n] = a[n] + n,\alpha = \frac{1 + \sqrt5}{2}a[n]=nα,b[n]=a[n]+n,α=21+5??,這個時候是可以確定必敗狀態的。
這里就不詳細展開證明了。
威佐夫博弈拓展:
兩種操作:一、同時在兩堆分別取x,y,∣x?y∣<=kx, y, \mid x - y \mid <= kx,y,∣x?y∣<=k。二、在某一堆上取任意個數。(每次取不為0)
對于給定的限定kkk,于是題目判定變成了a[n]=nα,b[n]=a[n]+(k+1)na[n] = n \alpha, b[n] = a[n] + (k + 1)na[n]=nα,b[n]=a[n]+(k+1)n,帶入kkk等于0的時候也就是普通情況下成立,
所以我們可以先解得α\alphaα,然后再通過二分去尋找是否有符合要求的nnn,這個時候α\alphaα的有關方程是1α+1α+k+1=1\frac{1}{\alpha} + \frac{1}{\alpha + k + 1} = 1α1?+α+k+11?=1。
即可解的方程然后帶入驗證即可。
取(2堆)石子游戲(普通威佐夫)
/*Author : lifehappy */ #pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h>#define mp make_pair #define pb push_back #define endl '\n' #define mid (l + r >> 1) #define lson rt << 1, l, mid #define rson rt << 1 | 1, mid + 1, r #define ls rt << 1 #define rs rt << 1 | 1using namespace std;typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii;const double pi = acos(-1.0); const double eps = 1e-7; const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x; }int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int a, b;while(cin >> a >> b && (a + b)) {map<int, int> MP;if(a < b) swap(a, b);int k = (a - b) * ((1 + sqrt(5)) / 2);if(k == b) {puts("0");continue;}puts("1");for(int i = 1; i <= b; i++) {int n = a - i, m = b - i;int k = (n - m) * ((1 + sqrt(5)) / 2);if(k == m) {printf("%d %d\n", m, n);}}for(int i = 1; i <= a; i++) {int n = a - i, m = b;if(n < m) swap(n, m);int k = (n - m) * ((1 + sqrt(5)) / 2);if(MP[m] == n) continue;MP[m] = n;if(k == m) {printf("%d %d\n", min(n, m), max(n, m));}}for(int i = 1; i <= b; i++) {int n = a, m = b - i;if(n < m) swap(n, m);int k = (n - m) * ((1 + sqrt(5)) / 2);if(MP[m] == n) continue;MP[m] = n;if(k == m) {printf("%d %d\n", m, n);}}}return 0; }Slime and Stones(拓展威佐夫)
/*Author : lifehappy */ #pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h>#define mp make_pair #define pb push_back #define endl '\n' #define mid (l + r >> 1) #define lson rt << 1, l, mid #define rson rt << 1 | 1, mid + 1, r #define ls rt << 1 #define rs rt << 1 | 1using namespace std;typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii;const double pi = acos(-1.0); const double eps = 1e-7; const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x; }ll calc(ll n, ll k) {double A = 1, B = k - 2, C = -k;double a = (sqrt(B * B - 4 * A * C) - B) / (2 * A);ll l = 1, r = 1e9;while(l < r) {ll Mid = l + r >> 1;ll now = Mid * a + k * Mid;if(now >= n) r = mid;else l = mid + 1;}ll now = l * a + k * l;return now == n ? l : -1; }int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int T = read();while(T--) {ll a = read(), b = read(), k = read() + 1;if(a < b) swap(a, b);ll n = calc(a, k);if(n == -1) puts("1");else {if(a - b == n * k) puts("0");else puts("1");}}return 0; }總結
- 上一篇: HDU 6607 Easy Math P
- 下一篇: android 极简桌面壁纸,极简桌面(