威佐夫博弈
普通威佐夫博弈:
两种操作:一、同时在两堆上取相同的个数。二、在某一堆上取任意个数。(每次取不为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;
}