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\n", sg[a] ? 1 : 2); 33 } 34 35 return 0; 36 }