2940: [Poi2000]条纹(Multi_SG)
2940: [Poi2000]条纹
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 114 Solved: 72
[Submit][Status][Discuss]
Description
条纹游戏是一个双人的游戏。所需要的物品有一个棋盘以及三种颜色的长方形条纹,这三种颜色分别是红色、绿色和蓝色。所有的红色条纹的尺寸是c*1,所有的绿色条纹的尺寸是z*1,所有的蓝色条纹的尺寸是n*1,这里c,z,n是正整数。每种颜色的条纹每个游戏者都拥有无限多个。
一个棋盘是一个尺寸为p*1的长方形,由p个1*1的方格组成。
游戏者轮流走,每一步都是由一个游戏者任选一种长方形条纹覆盖到棋盘上,并要求遵循以下规则:
l 条纹不能伸出棋盘之外。
l 不能覆盖在已有的条纹之上(即使部分也不行)。
l 条纹的边缘必须与棋盘方格的边缘相重叠。谁不能再走,谁就输了。
先手是指在游戏中第一个走的游戏者。那么是否不管后手怎么走,先手都有必胜策略呢?
任务:
写一个程序:
l 读入条纹的尺寸以及至少一个棋盘的尺寸。
l 对每一个给出的棋盘判断先手是否必胜。
l 将结果输出。
Input
第一行包含三个整数c,z,n(1<=c,z,,n<=1000),表示三种条纹的长度,依次为红色,绿色以及蓝色。每两个数之间都用空格隔开。
文件的第二行包括一个整数m(1 <= m <= 1000)表示需要考虑的不同棋盘个数。以下3到m+2行每行包括一个整数p(1<=p<=1000)。第i+2行表示第i个棋盘的长度。
Output
应当包含m行。只有一个数字应当被写入文件的第i行:
l 1—如果对第i个棋盘先手有必胜策略。
l 2—其它。
Sample Input
1 5 1
3
1
5
6
3
1
5
6
Sample Output
1
1
2
code
1 #include<cstdio> 2 #include<cstring> 3 #include<set> 4 5 using namespace std; 6 int c,z,n,p,T; 7 int sg[1010]; 8 9 int get_SG(int x) { 10 if (sg[x]!=-1) return sg[x]; 11 set<int>s; 12 for (int i=0; i<=(x-c); ++i) //枚举左边的长度 13 s.insert(get_SG(i)^get_SG(x-i-c)); 14 for (int i=0; i<=(x-z); ++i) 15 s.insert(get_SG(i)^get_SG(x-i-z)); 16 for (int i=0; i<=(x-n); ++i) 17 s.insert(get_SG(i)^get_SG(x-i-n)); 18 for (int j=0; ; ++j) 19 if (!s.count(j)) {sg[x]=j;break;} 20 return sg[x]; 21 } 22 int main () { 23 memset(sg,-1,sizeof(sg)); 24 sg[0] = 0; 25 scanf("%d%d%d%d",&c,&z,&n,&T); 26 while (T--) { 27 scanf("%d",&p); 28 if (get_SG(p)==0) puts("2"); 29 else puts("1"); 30 } 31 return 0; 32 }
开始理解错题目了。。。TLE
1 #include<cstdio> 2 #include<cstring> 3 #include<set> 4 5 using namespace std; 6 int c,z,n,p,T; 7 int sg[1010][1010]; 8 9 int get_SG(int l,int r) { 10 if (l > r) return 0; 11 if (sg[l][r]!=-1) return sg[l][r]; 12 set<int>s; 13 for (int i=l; i<=(r-c+1); ++i) 14 s.insert(get_SG(l,i-1)^get_SG(i+c,r)); 15 for (int i=l; i<=(r-z+1); ++i) 16 s.insert(get_SG(l,i-1)^get_SG(i+z,r)); 17 for (int i=l; i<=(r-n+1); ++i) 18 s.insert(get_SG(l,i-1)^get_SG(i+n,r)); 19 for (int j=0; ; ++j) 20 if (!s.count(j)) {sg[l][r]=j;break;} 21 return sg[l][r]; 22 } 23 int main () { 24 memset(sg,-1,sizeof(sg)); 25 sg[0][0] = 0; 26 scanf("%d%d%d%d",&c,&z,&n,&T); 27 while (T--) { 28 scanf("%d",&p); 29 if (get_SG(1,p)==0) puts("2"); 30 else puts("1"); 31 } 32 return 0; 33 }