题目传送:Win the Game
最近正在慢慢体会博弈里面的SG函数的意义
此题是最简单的SG博弈问题,只需打个表就OK了
AC代码:
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <utility>
#include <iostream>
#include <algorithm>
#include <functional>
#define LL long long
#define INF 0x7fffffff
using namespace std;
int sg[55];
int vis[55];
void get_sg() {
sg[0] = 0;
sg[1] = 0;
for(int i = 2; i < 55; i ++) {
memset(vis, 0, sizeof(vis));
vis[sg[i - 2]] = 1;
for(int j = 1; j + 2 <= i; j ++) {
vis[sg[j] ^ sg[i - j - 2]] = 1;
}
for(int j = 0;; j ++) {
if(!vis[j]) {
sg[i] = j;
break;
}
}
}
}
int n;
int main() {
get_sg();
//for(int i = 0; i < 55; i ++) cout << sg[i] << " ";
while(scanf("%d", &n) != EOF) {
int SG = 0, t;
for(int i = 0; i < n; i ++) {
scanf("%d", &t);
SG ^= sg[t];
}
if(SG == 0) {
printf("No\n");
}
else printf("Yes\n");
}
return 0;
}
题目传送:Let’s play a game
AC代码:
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <utility>
#include <iostream>
#include <algorithm>
#include <functional>
#define LL long long
#define INF 0x7fffffff
using namespace std;
int T;
int main() {
scanf("%d", &T);
while(T --) {
int n, t, cnt = 0;;
int SG = 0;
scanf("%d", &n);
for(int i = 0; i < n; i ++) {
scanf("%d", &t);
SG ^= t;
if(t > 1) cnt ++;
}
if(cnt == 0) {
if(SG == 1) {
printf("2\n");
}
else printf("1\n");
}
else {
if(SG) {
printf("1\n");
}
else printf("2\n");
}
}
return 0;
}
题目传送:A Game Between Alice and Bob
和之前UVA那个题类似,也是打表筛出素因子个数,然后套SG即可
AC代码:
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <utility>
#include <iostream>
#include <algorithm>
#include <functional>
#define LL long long
#define INF 0x7fffffff
using namespace std;
const int maxn = 5000005;
int n;
int a[100005];
int chu[maxn];
int to[maxn];
void init() {
to[1] = 0;
for(int i = 2; i < maxn; i ++) chu[i] = i;
for(int i = 2; i < maxn; i ++) {
if(to[i]) continue;
to[i] ++;
for(int j = 2 * i; j < maxn; j += i) {
while(chu[j] % i == 0) {
to[j] ++;
chu[j] /= i;
}
}
}
}
int main() {
init();
//for(int i = 1; i < 10; i ++) cout << to[i] << " ";
int cas = 1;
while(scanf("%d", &n) != EOF) {
int SG = 0, t;
for(int i = 0; i < n; i ++) {
scanf("%d", &t);
a[i] = to[t];
SG ^= a[i];
}
if(SG == 0) {
printf("Test #%d: Bob\n", cas);
}
else {
printf("Test #%d: Alice", cas);
for(int i = 0; i < n; i ++) {
if(a[i] > (a[i] ^ SG)) {
printf(" %d\n", i + 1);
break;
}
}
}
cas ++;
}
return 0;
}
题目传送:Human or Pig
注意题目要输出的P点和H点的含义。
含义是:
AC代码:
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <utility>
#include <iostream>
#include <algorithm>
#include <functional>
#define LL long long
#define INF 0x7fffffff
using namespace std;
const int maxn = 40005;
int mp[maxn];//由于X*Y<=40000,但是这里开40000*40000的数组又太大了,所以这里我们应该用一维数组来模拟二维数组
int X, Y;//行数以及列数
int& get_pos(int x, int y) {//获取一维数组上对应的二维数组上的那个值
return mp[(x - 1) * Y + y];
}
//这里需要注意P点和H点的含义,即
//H点代表此时只能是人类,才能确保落入水中时的状态是猪
//P点代表此时是猪,也能确保落入水中时的状态是猪,这一步只需要保证他的后继状态都是H或者直接掉入水中即可
//
//通俗一点的来说就是随便乱走都可以满足条件的就是P点,然后可以根据后继状态有P来确保满足条件的就是H点
char get_char(int x, int y) {//获取一次的
int &ret = get_pos(x, y);
ret = 'P';//先初始化为P点,P点代表此时是猪,因为猪是没思想的,可以随便走,所以初始化为这个
//只要当前状态的后继状态出现了P点就可以转化成H点,因为H点代表人类,人类是有思想的,可以指定选择走到P点,而走到P点后随意走都可以满足条件
//如果当前状态的后继状态出现了P点,而又没有转化,则当前不能确保能满足条件
for(int k = 1; y > k * x; k ++) {
if(get_pos(x, y - k * x) == 'P') {
ret = 'H';
break;
}
}
for(int k = 1; x > k * y; k ++) {
if(get_pos(x - k * y, y) == 'P') {
ret = 'H';
break;
}
}
return ret;
}
int main() {
int cas = 1;
while(scanf("%d %d", &X, &Y) != EOF) {
printf("Case #%d:\n", cas ++);
for(int i = 1; i <= X; i ++) {
for(int j = 1; j <= Y; j ++) {
putchar(get_char(i, j));
}
puts("");
}
}
return 0;
}