链接:http://acm.hdu.edu.cn/showproblem.php?pid=2176
题意:nim游戏,先手必败输出no,先手必胜输出yes和第一步的每一种取法。
思路:基础nim,顺序输出取法就行。
这是篇nim博弈入门的经典帖子http://acm.hdu.edu.cn/forum/read.php?fid=9&tid=10617
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<set>
using namespace std;
int a[200005];
int main(){
int m;
while (scanf("%d", &m), m){
int c = 0;
for (int i = 0; i < m; i++){
scanf("%d", &a[i]);
c ^= a[i];
}
if (c == 0){
printf("No\n");
continue;
}
printf("Yes\n");
for (int i = 0; i < m; i++){
if ((a[i] ^ c) < a[i])
printf("%d %d\n", a[i], a[i] ^ c);
}
}
return 0;
}
因为nim博弈的性质不熟悉超时一发,不需要每个数都判断是否含有c的最高位,只要含有c的最高位,与c亦或一定小于原数。
超时代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<set>
using namespace std;
int a[200005];
int main(){
int m;
while (scanf("%d", &m), m){
int c = 0;
for (int i = 0; i < m; i++){
scanf("%d", &a[i]);
c ^= a[i];
}
if (c == 0){
printf("No\n");
continue;
}
printf("Yes\n");
int cc = 1;
while ((cc << 1) <= c)cc <<= 1;
int t = cc << 1;
for (int i = 0; i < m; i++){
if (a[i] % t >= cc)
printf("%d %d\n", a[i], a[i] ^ c);
}
}
return 0;
}