S-Nim

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

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
 
 

题意:首先输入K 表示一个集合的大小  之后输入集合 表示对于这对石子只能去这个集合中的元素的个数

之后输入 一个m 表示接下来对于这个集合要进行m次询问

之后m行 每行输入一个n 表示有n个堆  每堆有n1个石子  问这一行所表示的状态是赢还是输 如果赢输入W否则L

思路:对于n堆石子 可以分成n个游戏 之后把n个游戏合起来就好了
 #include <bits/stdc++.h>
using namespace std; const int MAXN = + ;
const int MAXM = + ; int f[MAXN];//f[0]存合法移动个数
int sg[MAXM];
bool exist[MAXN];//hash, sg不会超过合法移动个数MAXN void getSg(int n)
{
int i, j;
sg[] = ;
for (i = ; i <= n; ++i) {
memset(exist, false, sizeof(exist));
for (j = ; j <= f[] && f[j] <= i; ++j) {
exist[sg[i - f[j]]] = true;
}
for (j = ; j < MAXN; ++j) {
if (!exist[j]) {
sg[i] = j;
break;
}
}
}
} int main()
{
int k;//, s;
int m;
int l, hi;
int i, j;
int sum; while (~scanf("%d", &k)) {
if (k == ) {
break;
}
f[] = k;
for (i = ; i <= k; ++i) {
scanf("%d", &f[i]);
}
sort(f + , f + + k);
getSg(); scanf("%d", &m);
for (i = ; i < m; ++i) {
scanf("%d", &l);
sum = ;
for (j = ; j < l; ++j) {
scanf("%d", &hi);
sum ^= sg[hi];
}
if (sum != ) {
printf("W");
} else {
printf("L");
}
}
printf("\n"); }
return ;
}
 #include <bits/stdc++.h>
using namespace std; const int MAXN = + ;
const int MAXM = + ; int s[MAXN];
int sg[MAXM];
int n;//s中的个数 int dfsSg(int x)
{
if (sg[x] != -) {
return sg[x];
}
int i;
bool vis[MAXN];//sg范围
memset(vis, false, sizeof(vis));
for (i = ; i < n && s[i] <= x; ++i) {
dfsSg(x - s[i]);
vis[sg[x - s[i]]] = true;
}
for (i = ; i <= x; ++i) {
if (!vis[i]) {
sg[x] = i;
break;
}
}
return sg[x];
} int main()
{
int k;//, s;
int m;
int l, hi;
int i, j;
int sum; while (~scanf("%d", &k)) {
if (k == ) {
break;
}
n = k;
for (i = ; i < k; ++i) {
scanf("%d", &s[i]);
}
sort(s, s + k);
memset(sg, -, sizeof(sg));
scanf("%d", &m);
for (i = ; i < m; ++i) {
scanf("%d", &l);
sum = ;
for (j = ; j < l; ++j) {
scanf("%d", &hi);
sum ^= dfsSg(hi);
}
if (sum != ) {
printf("W");
} else {
printf("L");
}
}
printf("\n"); }
return ;
}

hdu 1536/ hdu 1944 S-Nim(sg函数)的更多相关文章

  1. hdu 3032 Nim or not Nim? sg函数 难度:0

    Nim or not Nim? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  2. HDU 1848 Fibonacci again and again(SG函数)

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  3. hdu 4559 涂色游戏(对SG函数的深入理解,推导打SG表)

    提议分析: 1 <= N <= 4747 很明显应该不会有规律的,打表发现真没有 按题意应该分成两种情况考虑,然后求其异或(SG函数性质) (1)找出单独的一个(一列中只有一个) (2)找 ...

  4. hdu 3980 Paint Chain 组合游戏 SG函数

    题目链接 题意 有一个\(n\)个珠子的环,两人轮流给环上的珠子涂色.规定每次涂色必须涂连续的\(m\)颗珠子,无法继续操作的人输.问先手能否赢. 思路 参考 转化 第一个人取完之后就变成了一条链,现 ...

  5. HDU 1848 Fibonacci again and again SG函数做博弈

    传送门 题意: 有三堆石子,双方轮流从某堆石子中去f个石子,直到不能取,问先手是否必胜,其中f为斐波那契数. 思路: 利用SG函数求解即可. /* * @Author: chenkexing * @D ...

  6. 多校6 1003 HDU5795 A Simple Nim (sg函数)

    思路:直接打表找sg函数的值,找规律,没有什么技巧 还想了很久的,把数当二进制看,再类讨二进制中1的个数是必胜或者必败状态.... 打表: // #pragma comment(linker, &qu ...

  7. hdu 3032 Nim or not Nim? (SG函数博弈+打表找规律)

    Nim or not Nim? Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Sub ...

  8. HDU 3032 Nim or not Nim (sg函数)

    加强版的NIM游戏,多了一个操作,可以将一堆石子分成两堆非空的. 数据范围太大,打出sg表后找规律. # include <cstdio> # include <cstring> ...

  9. HDU 1729 Stone Game 石头游戏 (Nim, sg函数)

    题意: 有n个盒子,每个盒子可以放一定量的石头,盒子中可能已经有了部分石头.假设石头无限,每次可以往任意一个盒子中放石头,可以加的数量不得超过该盒中已有石头数量的平方k^2,即至少放1个,至多放k^2 ...

随机推荐

  1. 洛谷 P4171 [JSOI]满汉全席

    洛谷 最近刚刚学的2-sat,就刷了这道裸题. 2-sat问题一般是用tarjan求的,当出现(x,y)或(!x,y)或(x,!y)三种选择时,我们可以把!x->y,!y->x连边. 然后 ...

  2. 开发人员必备的 Chrome 扩展

    Firebug:不用多介绍了吧 https://chrome.google.com/webstore/detail/bmagokdooijbeehmkpknfglimnifench ChromeSni ...

  3. app开发流程有哪些

    app开发流程是需求方和供求方相互协调的过程,一般分为需求分析.功能设计.功能实现.项目测试.上线等几个步骤,下面我们就来一起看看ytkah团队进行app开发各个流程主要做哪些事情,让您对app开发设 ...

  4. Java并发—线程池框架Executor总结(转载)

    为什么引入Executor线程池框架 new Thread()的缺点 每次new Thread()耗费性能 调用new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制创建,之间相互竞 ...

  5. python更新模块

    pip install -U 模块名 # 这是 python2+ 版本的用法更新模块 pip3 install -U 模块名 # 这是 python3+ 版本的用法更新模块

  6. Informatica can bind a LONG value only for insert into a LONG column Oracle

    Informatica实现etl同步表数据信息时 报: Severity Timestamp Node Thread Message Code Message ERROR 2016/8/8 17:32 ...

  7. Capslock and Esc

    将Caps Lock转换成Esc(windows and linux) 1. linux 下将Caps Lock 转换成Esc 作为一个vimer,Caps Lock对我(还有其他很多人)来说根本就是 ...

  8. Socke---转

      Socket,又称为套接字,Socket是计算机网络通信的基本的技术之一.如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都是基于Socket实现的.本文会介绍一下基于TCP/IP ...

  9. ubuntu里设置从串口登录

    1) Create a file called /etc/init/ttyS0.conf containing the following: # ttySAC0 - getty # # This se ...

  10. PHP 获取真实IP地址

    function getClientIp($type = 0) { $type = $type ? 1 : 0; static $ip = NULL; if ($ip !== NULL) return ...