思路:
第一堆:SG = n % 3;
第二堆:无规律,打表即可,用hash比set快很多;
第三堆:SG = n;
第四堆:无规律
第五堆:SG = n % 2;
第六堆:SG = n % (i + 1 ),i表示第i堆;
AC代码:
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int>
typedef long long LL;
const int maxn = 1e3 + 5;
void in(int &a) {
char ch;
while((ch=getchar()) < '0' || ch >'9');
for(a = 0; ch >= '0' && ch <= '9'; ch = getchar()) {
a = a * 10 + ch - '0';
}
}
int f[100], SG[2][maxn], o[maxn];
void init() {
set<int>s;
f[0] = 1;
f[1] = 2;
SG[0][0] = SG[1][0] = 0;
for(int i = 2; i < 100; ++i) f[i] = f[i-1] + f[i-2];
//斐波那契
for(int i = 1; i <= 1000; ++i) {
s.clear();
for(int j = 0; j < 100; ++j) {
if(f[j] > i) break;
s.insert(SG[0][i-f[j]]);
}
for(int j = 0; j <= 1000; ++j) {
if(!s.count(j)) {
SG[0][i] = j;
break;
}
}
}
//偶数
o[0] = 1;
for(int i = 1; i <= 600; ++i) o[i] = i * 2;
for(int i = 1; i <= 1000; ++i) {
s.clear();
for(int j = 0; j < 550; ++j) {
if(o[j] > i) break;
s.insert(SG[1][i-o[j]]);
}
for(int j = 0; j <= 1000; ++j) {
if(!s.count(j)) {
SG[1][i] = j;
break;
}
}
}
}
int main() {
init();
int n;
while(scanf("%d", &n) == 1 && n) {
int x, res = 0;
for(int i = 1; i <= n; ++i) {
in(x);
switch(i){
case 1: res ^= x%3; break;
case 2: res ^= SG[0][x]; break;
case 3: res ^= x; break;
case 4: res ^= SG[1][x]; break;
case 5: res ^= x%2; break;
default: res ^= x % (i+1); break;
}
}
if(res) printf("Yougth\n");
else printf("Hrdv\n");
}
return 0;
}
如有不当之处欢迎指出!