这题是男人8题=_=我是看到网上那篇叫寻找必败态——一类博弈问题的快速解法时看到这道题才做的,话说文章作者神一样的分析思路至今学不来,还是只会一点基本的SG函数的求法,Bash,Wythoff,Nim这三个基本模型和三个Nim的变体(AntiNim、LaskerNim、StairCaseNIm),博弈真是漫漫长路啊=_=‘
靠寻找必败态求解组合博弈问题思维量较大,一般是靠小数据计算,然后推规律,最后提出猜想,验证猜想,最后得解,验证猜想无非是看以自己的猜想能否满足博弈树合法的三个条件即:1、最终态必然是必败态。2、必败态只能走向必胜态。3、必胜态总能找到一种情形走到必败态。——即可。
下面是代码,当时考虑去重是用的是vector+unique觉得看起来比较洋气,实际上傻X了,要是有两个以上的重数也会被去掉,而必败态是在偶数堆(2N堆)中N堆石子两两相等,结果WA了多发orz
//POJ-1740.cpp #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <ctime> #include <climits> #include <cctype> #include <algorithm> #include <iostream> #include <string> #include <stack> #include <map> #include <set> #include <queue> #include <utility> #include <vector> #include <bitset> #include <functional> using namespace std; //const double pai = acos(-1.0); const double pai = 3.14159265358979323846; const int INF = 0x3f3f3f3f; typedef long long love_live; int arr[117]; int main(int argc, char const *argv[]) { #ifndef ONLINE_JUDGE // freopen("output", "w", stdout); freopen("input", "r", stdin); #endif int n, m, i, j, k; while(scanf("%d", &n) != EOF){ if(n == 0){ break; } if(n % 2 != 0){ for(i = 0; i < n; ++i){ scanf("%d", &j); } printf("1\n"); continue; } else{ int flag = 0; memset(arr, 0, sizeof(arr)); for(i = 0; i < n; ++i){ scanf("%d", &arr[i]); } sort(arr, arr + n); for(i = 0; i < (n / 2); i += 2){ if(arr[i] != arr[i + 1]){ flag = 1; break; } } if(flag == 1){ printf("1\n"); } else{ printf("0\n"); } } } return 0; }