BZOJ2940 条纹

条纹游戏是一个双人的游戏。所需要的物品有一个棋盘以及三种颜色的长方形条纹,这三种颜色分别是红色、绿色和蓝色。所有的红色条纹的尺寸是c*1,所有的绿色条纹的尺寸是z*1,所有的蓝色条纹的尺寸是n*1,这里c,z,n是正整数。每种颜色的条纹每个游戏者都拥有无限多个。
一个棋盘是一个尺寸为p*1的长方形,由p个1*1的方格组成。
游戏者轮流走,每一步都是由一个游戏者任选一种长方形条纹覆盖到棋盘上,并要求遵循以下规则:
条纹不能伸出棋盘之外。
不能覆盖在已有的条纹之上(即使部分也不行)。
条纹的边缘必须与棋盘方格的边缘相重叠。谁不能再走,谁就输了。
先手是指在游戏中第一个走的游戏者。那么是否不管后手怎么走,先手都有必胜策略呢?

解:暴力sg即可,发现复杂度是n²的。

 1 #include <bits/stdc++.h>
 2 
 3 const int N = 1010;
 4 
 5 int bin[N], sg[N];
 6 
 7 int main() {
 8     int a, b, c, n;
 9     scanf("%d%d%d", &a, &b, &c);
10     for(int i = std::min(std::min(a, b), c); i <= 1000; i++) {
11         memset(bin, 0, sizeof(bin));
12         for(int j = 0; j + a <= i; j++) {
13             bin[sg[j] ^ sg[i - j - a]]++;
14         }
15         for(int j = 0; j + b <= i; j++) {
16             bin[sg[j] ^ sg[i - j - b]]++;
17         }
18         for(int j = 0; j + c <= i; j++) {
19             bin[sg[j] ^ sg[i - j - c]]++;
20         }
21         for(int j = 0; ; j++) {
22             if(!bin[j]) {
23                 sg[i] = j;
24                 break;
25             }
26         }
27     }
28 
29     scanf("%d", &n);
30     for(int i = 1; i <= n; i++) {
31         scanf("%d", &a);
32         printf("%d
", sg[a] ? 1 : 2);
33     }
34 
35     return 0;
36 }
AC代码
原文地址:https://www.cnblogs.com/huyufeifei/p/10552259.html