S-Nim

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3077    Accepted Submission(s): 1361

Problem Description
Arthur and his sister Caroll have been playing a game called Nim for some time now. Nim is played as follows:

The starting position has a number of heaps, all containing some, not necessarily equal, number of beads.

The players take turns chosing a heap and removing a positive number of beads from it.

The first player not able to make a move, loses.

Arthur and Caroll really enjoyed playing this simple game until they recently learned an easy way to always be able to find the best move:

Xor the number of beads in the heaps in the current position (i.e. if we have 2, 4 and 7 the xor-sum will be 1 as 2 xor 4 xor 7 = 1).

If the xor-sum is 0, too bad, you will lose.

Otherwise, move such that the xor-sum becomes 0. This is always possible.

It is quite easy to convince oneself that this works. Consider these facts:

The player that takes the last bead wins.

After the winning player's last move the xor-sum will be 0.

The xor-sum will change after every move.

Which means that if you make sure that the xor-sum always is 0 when you have made your move, your opponent will never be able to win, and, thus, you will win.

Understandibly it is no fun to play a game when both players know how to play perfectly (ignorance is bliss). Fourtunately, Arthur and Caroll soon came up with a similar game, S-Nim, that seemed to solve this problem. Each player is now only allowed to remove a number of beads in some predefined set S, e.g. if we have S =(2, 5) each player is only allowed to remove 2 or 5 beads. Now it is not always possible to make the xor-sum 0 and, thus, the strategy above is useless. Or is it?

your job is to write a program that determines if a position of S-Nim is a losing or a winning position. A position is a winning position if there is at least one move to a losing position. A position is a losing position if there are no moves to a losing position. This means, as expected, that a position with no legal moves is a losing position.

 
Input
Input consists of a number of test cases. For each test case: The first line contains a number k (0 < k ≤ 100 describing the size of S, followed by k numbers si (0 < si ≤ 10000) describing S. The second line contains a number m (0 < m ≤ 100) describing the number of positions to evaluate. The next m lines each contain a number l (0 < l ≤ 100) describing the number of heaps and l numbers hi (0 ≤ hi ≤ 10000) describing the number of beads in the heaps. The last test case is followed by a 0 on a line of its own.
 
Output
For each position: If the described position is a winning position print a 'W'.If the described position is a losing position print an 'L'. Print a newline after each test case.

 
Sample Input
2 2 5
3
2 5 12
3 2 4 7
4 2 3 7 12
5 1 2 3 4 5
3
2 5 12
3 2 4 7
4 2 3 7 12
0
 
Sample Output
LWW
WWL
 
Source
 
Recommend
LL
 
题意:
首先输入K 表示一个集合的大小  之后输入集合 表示对于这对石子只能去这个集合中的元素的个数
之后输入 一个m 表示接下来对于这个集合要进行m次询问 
之后m行 每行输入一个n 表示有n个堆  每堆有n1个石子  问这一行所表示的状态是赢还是输 如果赢输入W否则L
 
思路:
对于n堆石子 可以分成n个游戏 之后把n个游戏合起来就好了
 
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
//注意 S数组要按从小到大排序 SG函数要初始化为-1 对于每个集合只需初始化1边
//不需要每求一个数的SG就初始化一边
int SG[10100],n,m,s[102],k;//k是集合s的大小 S[i]是定义的特殊取法规则的数组
int dfs(int x)//求SG[x]模板
{
if(SG[x]!=-1) return SG[x];
bool vis[110];
memset(vis,0,sizeof(vis)); for(int i=0;i<k;i++)
{
if(x>=s[i])
{
dfs(x-s[i]);
vis[SG[x-s[i]]]=1;
}
}
int e;
for(int i=0;;i++)
if(!vis[i])
{
e=i;
break;
}
return SG[x]=e;
}
int main()
{
int cas,i;
while(scanf("%d",&k)!=EOF)
{
if(!k) break;
memset(SG,-1,sizeof(SG));
for(i=0;i<k;i++) scanf("%d",&s[i]);
sort(s,s+k);
scanf("%d",&cas);
while(cas--)
{
int t,sum=0;
scanf("%d",&t);
while(t--)
{
int num;
scanf("%d",&num);
sum^=dfs(num);
// printf("SG[%d]=%d\n",num,SG[num]);
}
if(sum==0) printf("L");
else printf("W");
}
printf("\n");
}
return 0;
}

 
 下面是对SG打表的做法
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int K=101;
const int H=10001;//H是我们要打表打到的最大值
int k,m,l,h,s[K],sg[H],mex[K];///k是集合元素的个数 s[]是集合 mex大小大约和集合大小差不多
///注意s的排序
void sprague_grundy()
{
int i,j;
sg[0]=0;
for (i=1;i<H;i++){
memset(mex,0,sizeof(mex));
j=1;
while (j<=k && i>=s[j]){
mex[sg[i-s[j]]]=1;
j++;
}
j=0;
while (mex[j]) j++;
sg[i]=j;
}
} int main(){
int tmp,i,j; scanf("%d",&k);
while (k!=0){
for (i=1;i<=k;i++)
scanf("%d",&s[i]);
sort(s+1,s+k+1); //这个不能少
sprague_grundy();
scanf("%d",&m);
for (i=0;i<m;i++){
scanf("%d",&l);
tmp=0;
for (j=0;j<l;j++){
scanf("%d",&h);
tmp=tmp^sg[h];
}
if (tmp)
putchar('W');
else
putchar('L');
}
putchar('\n');
scanf("%d",&k);
}
return 0;}

hdu 1536 SG函数模板题的更多相关文章

  1. HDU 1536 sg函数

    S-Nim Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  2. UVA 10820 欧拉函数模板题

    这道题就是一道简单的欧拉函数模板题,需要注意的是,当(1,1)时只有一个,其他的都有一对.应该对欧拉函数做预处理,显然不会超时. #include<iostream> #include&l ...

  3. (hdu step 7.2.1)The Euler function(欧拉函数模板题——求phi[a]到phi[b]的和)

    题目: The Euler function Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...

  4. HDU 1847-Good Luck in CET-4 Everybody!-博弈SG函数模板

    Problem Description 大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此.当然,作为在考场浸润了十几载 ...

  5. hdu1536&&hdu3023 SG函数模板及其运用

    S-Nim Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status ...

  6. SG函数模板(转)

    ps:sg[i]为0表示i节点先手必败. 首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数.例如mex{0,1,2,4}=3.me ...

  7. HDU 2222 AC自动机模板题

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 我现在对AC自动机的理解还一般,就贴一下我参考学习的两篇博客的链接: http: ...

  8. HDU 1251 Trie树模板题

    1.HDU 1251 统计难题  Trie树模板题,或者map 2.总结:用C++过了,G++就爆内存.. 题意:查找给定前缀的单词数量. #include<iostream> #incl ...

  9. HDU 3065 (AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 题目大意:多个模式串,范围是大写字母.匹配串的字符范围是(0~127).问匹配串中含有哪几种模 ...

随机推荐

  1. Xcode6中怎么添加空工程模板

    亲们!是不是还在为Xcode中不能创建空工程模板苦恼,轩哥为大家准备了一个脚本,可以在Xcode6中直接创建空工程,跟以前一样一样的! 按照以下要求就可以了!下载地址:里面有一个文档有详细的步骤htt ...

  2. ZOJ 3607 Lazier Salesgirl 贪心

    这个题比上个题简单得多,也是超过W时间会睡着,睡着就再也不会卖了,顾客按时间顺序来的,但是可能有顾客同时到(同时到如果醒着就全卖了),并且每个人只买一块面包,也是求最大的W,使得卖出面包的平均价格最高 ...

  3. Xcode6项目运行在真机上未铺满整个屏幕

    如图 解决见图: 再次运行:

  4. QT全平台设置图标,全平台静态编译 good

    1.  概述 当我们用QT写好了一个软件,要把你的程序分享出去的时候,不可能把编译的目录拷贝给别人去运行.编译好的程序应该是一个主程序,加一些资源文件,再加一些动态链接库,高大上一些的还可以做一个安装 ...

  5. 转:Bootstrap研究 精巧的网格布局系统

    本网格布局系统属于Scaffolding(框架,布局)部分.在Scaffolding里面有(固定)网格布局(Grid System)和流式网格布局(Fluid Grid System).本文讨论第一种 ...

  6. eclipse 找不到application选项

    处理如下:Window-Preferences-Run/Debug-Perspectives 中的 And Build修改为如下

  7. JavaScript的实现

    了解了JavaScript是干什么的< 对一些词的理解 >,下面该知道它是怎么实现的. 一个完整的JavaScript是由三部分组成的,如下图 ECMAScript 可以为不同种类的宿主环 ...

  8. ONOS系统架构演进,实现高可用性解决方案

    上一篇文章<ONOS高可用性和可扩展性实现初探>讲到了ONOS系统架构在高可用.可扩展方面技术概况,提到了系统在分布式集群中怎样保证数据的一致性.在数据终于一致性方面,ONOS採用了Gos ...

  9. TCP三次握手和四次挥手具体解释

    三次握手:建立TCP须要三次握手才干建立, 先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源.Client端接收到ACK报文后也向Server段发生ACK ...

  10. android 从服务器上获取APK并下载安装

    简单的为新手做个分享.    网上有些资料,不过都是很零散,或是很乱的,有的人说看不懂.    一直有新手说 做到服务器更新APK时没有思路,这里做个简单的分享,希望有不同思路的可以讨论.     下 ...