题目来源:HDU 2177 取(2堆)石子游戏
题意:中文
思路:判断是否是必败态就不说了 做过hdu1527就知道了
现在如果不是必败态 输出下一步所有的必败态 题目要求先输出两堆都取的方案
首先 a = b 直接2堆取完
a != b 因为bi = ai+i 现在知道ak 和 bk 那么 k = bk-ak 得到k 求出 aj 和 bj 如果ak-aj == bk-bj && ak-aj > 0(aj, bj)是必败态 输出aj bj
然后是只取一堆的情况
假设a不变 求出对应的bk 如果b > bk 输出a bk
假设b不变 求出对应的ak 如果a > ak 输出ak b
注意公式 ai = i*(sqrt(5.0)+1)/2 bi = ai+i
现在如果b不变 b = i*(sqrt(5.0)+1)/2+i = i*(sqrt(5.0)+3)/2 求出i然后求出 ak
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; int main() { int a, b; while(scanf("%d %d", &a, &b) && (a||b)) { if(a > b) swap(a, b); //ai = i*(sqrt(5.0)+1)/2 //bi = ai+i double k = (sqrt(5.0)+1)/2; double k2 = (sqrt(5.0)+3)/2; double i = (int)(a/k); double i2 = (int)(a/k2); int a1 = i*k, b1 = a1+i; int a2 = (i+1)*k, b2 = a2+i+1; int a3 = (i2*k), b3 = a3+i2; int a4 = (i2+1)*k, b4 = a4+i2+1; if(a1 == a && b1 == b) puts("0"); else if(a2 == a && b2 == b) puts("0"); else { puts("1"); if(a == b) printf("%d %d\n", 0, 0); else { int j = b-a; int a3 = j*k, b3 = a3+j; if(a-a3 == b-b3 && a-a3 > 0) printf("%d %d\n", a3, b3); } if(a1 == a && b1 < b) printf("%d %d\n", a1, b1); if(a2 == a && b2 < b) printf("%d %d\n", a2, b2); if(a3 < b && b3 == a) printf("%d %d\n", a3, b3); if(a4 < b && b4 == a) printf("%d %d\n", a4, b4); } } return 0; }
HDU 2177 取(2堆)石子游戏 威佐夫博弈
时间: 2024-12-15 01:45:50