【原题在此】
Let us consider a game on a rectangular board m x 1 consisting of m elementary squares numbered successively from 1 to m. There are n pawns on the board, each on a distinct square. None of them occupies the square with number m. Each single move in the is the following action: the moving player picks a pawn from any occupied square chosen at will and places it on the first unoccupied square with a larger number. The two players make moves in turn. The one who puts a pawn on the last square, i.e. the square with a number m, wins.
In the case presented in the figure (m = 7), a player is allowed to move a pawn from square no. 2 to 4, from square no. 3 to 4 or from square no. 6 to 7. The latter ends the game. We say a player's move is winning if after making it he can win the game, no matter what moves his opponent makes.
Task reads the size of a board and the initial setup of pawns from the standard input, Input Output
Example 5 2 the correct answer is: 1 For the following input data: 5 2 the correct answer is: 0 |
【题目翻译】
在一个有M个格子的长条上,从左到右编号1到M。一些格子上方有一些棋子,一个格子只能放一个棋子,第M格没有放棋子。两个人轮流操作,每次操作是选择一枚棋子往右放,放在它右边距离它最近的一个空格里。最先把棋子放在第M格的人胜利。问先手必胜的第一步策略一共有多少种?
上图中,当前玩家可以将2中的硬币移动到4,或3中的硬币到4,或6中的硬币到7。
【输入格式】
第一行输入m,n 。第二行n个数分别表示每一枚硬币所在的位置。
【输出格式】
进一行,保证先行者胜利的策略数。
分析:
目测这题我自己是想不出来的了,原来可以转化为阶梯模型,也是听了scy讲了才知道~~
(转自:http://blog.sina.com.cn/s/blog_51cea4040100h0ab.html)
感觉博主很厉害很厉害,同时也是萌萌哒~~于是这题就转成了我们熟悉的阶梯模型了。
然后我开始打代码,打完之后,我的内心:
&&¥¥%%#这题好坑好坑好坑啊,各种情况都要考虑到才行。把这题转换成阶梯模型之后,偶数阶的棋子并不是没有用的!!对方案有巨大贡献啊!!可以把偶数阶的扫下去相当于奇数阶的增加了!!还有各种特判,都晕了~(数据大的直接不管了,好麻烦~~)
呵呵~
代码在这里,数据大的过不了TAT:
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 #include<algorithm>
6 #include<queue>
7 using namespace std;
8 #define Maxn 10000100
9
10 int a[Maxn],c[Maxn];
11 bool b[Maxn];
12
13 int main()
14 {
15 int m,n;
16 scanf("%d%d",&m,&n);
17 memset(b,0,sizeof(b));
18 for(int i=1;i<=n;i++)
19 {
20 scanf("%d",&a[i]);
21 b[a[i]]=1;
22 }
23 if(b[m-1]==1)
24 {
25 int i;
26 int sum=0;for(i=m-1;i>=1;i--) if(!b[i]) break;
27 printf("%d\n",m-1-i);
28 }
29 else
30 {
31 memset(c,0,sizeof(c));
32 int sum=0,st;
33 for(st=m-2;b[st];st--);
34 for(int i=st;i>=1;i--)
35 {
36 if(b[i]==0) sum++;
37 else c[sum]++;
38 }
39 int ans=0;
40 for(int i=1;i<=sum;i+=2) ans^=c[i];
41 if(ans==0) printf("0\n");
42 else
43 {
44 int mx=0;
45 for(int i=0;(1<<i)<=ans;i++)
46 if((1<<i)&ans) mx=(1<<i);
47 int h=0;
48 for(int i=1;i<=sum;i+=2)
49 if(c[i]&mx) h++;
50 for(int i=2;i<=sum;i+=2)
51 if(((ans^c[i-1])-c[i-1])>=0&&c[i]>=((ans^c[i-1])-c[i-1])) h++;
52 printf("%d\n",h);
53 }
54 }
55 return 0;
56 }
[POI2003/2004 stage I ]
2016-04-16 10:23:03