poj 2311

Cutting Game










Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 2844   Accepted: 1036

Description

Urej loves to play various types of dull games. He
usually asks other people to play with him. He says that playing those games can
show his extraordinary wit. Recently Urej takes a great interest in a new game,
and Erif Nezorf becomes the victim. To get away from suffering playing such a
dull game, Erif Nezorf requests your help. The game uses a rectangular paper
that consists of W*H grids. Two players cut the paper into two pieces of
rectangular sections in turn. In each turn the player can cut either
horizontally or vertically, keeping every grids unbroken. After N turns the
paper will be broken into N+1 pieces, and in the later turn the players can
choose any piece to cut. If one player cuts out a piece of paper with a single
grid, he wins the game. If these two people are both quite clear, you should
write a problem to tell whether the one who cut first can win or not.

Input

The input contains multiple test cases. Each test
case contains only two integers W and H (2 <= W, H <= 200) in one line,
which are the width and height of the original paper.

Output

For each test case, only one line should be
printed. If the one who cut first can win the game, print "WIN", otherwise,
print "LOSE".

Sample Input

2 2
3 2
4 2

Sample Output

LOSE
LOSE
WIN

Source

POJ
Monthly
,CHEN Shixi(xreborner)

sg函数

 1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5 #include <set>
6
7 using namespace std;
8
9 const int MAX_N = 205;
10 int dp[MAX_N][MAX_N];
11
12 int grundy(int w, int h) {
13 if(dp[w][h] != -1) return dp[w][h];
14
15 set<int> s;
16 for(int i = 2; w - i >= 2; i++) {
17 s.insert(grundy(i, h) ^ grundy(w - i,h));
18 }
19 for(int i = 2; h - i >= 2; ++i) {
20 s.insert(grundy(w, i) ^ grundy(w, h - i));
21 }
22
23 int res = 0;
24 while(s.count(res)) res++;
25 return dp[w][h] = res;
26 }
27
28 int main()
29 {
30 //freopen("sw.in","r",stdin);
31 int w, h;
32
33 for(int i = 1; i <= 200; ++i) {
34 for(int j = 1; j <= 200; ++j) dp[i][j] = -1;
35 }
36 while(~scanf("%d%d",&w,&h)) {
37 printf("%s\n",grundy(w, h) ? "WIN" : "LOSE");
38 }
39 //cout << "Hello world!" << endl;
40 return 0;
41 }

时间: 2024-10-05 10:19:38

poj 2311的相关文章

poj 2311 Cutting Game nim与状态的grundy值

题意: 给一个w*h的矩形,两人轮流只能沿格子的边缘横剪或竖剪,最先剪出1*1的格子的人获胜,问先手必胜还是必败. 分析: 此题要求对grundy值有理解.一个全局状态的grundy值是对游戏中某个状态的有效的描述,grundy值描述了当前状态的所有后继状态,比如n堆石子的nim游戏的grundy值是a1^a2^...an. 代码: //poj 2311 //sep9 #include <iostream> #include <set> using namespace std; c

POJ 2311 Cutting Game (sg函数)

给出一个N*M的纸片,每一次可以把一部分剪成两部分,谁剪出1*1的就赢了. http://poj.org/problem?id=2311 对于任何一个人,都不会先剪出1*n或者n*1,应该这样就必败了. 那我们考虑一个状态的后继中,最小的边也是2,这样就可以避免之前的问题,也不需要考虑类似ANTI-SG. 一旦出现2*2,2*3,3*2,这些都成了终止状态,不论怎么剪都会出现1*n,或者n*1 还是考察SG函数 # include<stdio.h> # include<algorithm

POJ 2311 Cutting Game [Multi-SG?]

传送门 题意:n*m的纸片,一次切成两份,谁先切出1*1谁胜 Multi-SG? 不太一样啊 本题的要求是后继游戏中任意游戏获胜就可以了.... 这时候,如果游戏者发现某一单一游戏他必败他就不会再玩了 $2*2,2*3,3*3$都不会再玩了(除非只剩下这样的纸片了),所以都可以认为是终止状态,必败 在此基础上按照Multi-SG递推就对了 #include <iostream> #include <cstdio> #include <algorithm> #includ

poj 2311 Cutting Game SG函数的运用 唉,,,

Cutting Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3227   Accepted: 1195 Description Urej loves to play various types of dull games. He usually asks other people to play with him. He says that playing those games can show his e

poj 2311 Cutting Game (SG)

题意: 有一张W*H的纸片. 每人每次可以横着撕或者竖着撕,先撕出1*1那一方胜. 数据范围: W and H (2 <= W, H <= 200) 思路: 很好抽象出游戏图的模型,用SG解决.直接看代码. 代码: int dp[maxn][maxn]; int sg(int w,int h){ if(dp[w][h]!=-1) return dp[w][h]; bool g[maxn]; mem(g,false); for(int i=2;i<=w/2;++i) g[sg(i,h)^s

POJ - 2311 Cutting Game

Description Urej loves to play various types of dull games. He usually asks other people to play with him. He says that playing those games can show his extraordinary wit. Recently Urej takes a great interest in a new game, and Erif Nezorf becomes th

0/1背包总结(持续更新...)

数字分组问题 Problem 1:给定n个物品,将它们分成两堆,使他们的质量之差最小,求这个最小值 poj 2311 Sol:差最小是0,此时分成的两堆的质量都是sum/2,因此让背包的总容量为sum/2,就是让某一堆尽量接近sum/2,此时两堆的差最小 Code: #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<map> usi

博弈论进阶之Multi-SG

Multi-Nim 从最简单的Nim模型开始 它的定义是这样的 有\(n\)堆石子,两个人可以从任意一堆石子中拿任意多个石子(不能不拿)或把一堆数量不少于\(2\)石子分为两堆不为空的石子,没法拿的人失败.问谁会胜利 博弈分析 这个问题的本质还是Nim游戏,可以利用SG定理来解释 通过观察不难不发现,操作一与普通的Nim游戏等价 操作二实际上是将一个游戏分解为两个游戏,根据SG定理,我们可以通过异或运算把两个游戏连接到一起,作为一个后继状态 煮个栗子 SG(3)的后继状态有\(\{ (0),(1

博弈论?【转载】

转自:https://www.cnblogs.com/sssy/p/8485307.html 巴什博奕: 两个顶尖聪明的人在玩游戏,有n个石子,每人可以随便拿1−m个石子,不能拿的人为败者,问谁会胜利 结论: 设当前的石子数为n=k∗(m+1) 即n 时先手一定失败 HDU1846 #include<iostream> using namespace std; int main() { int C,N,M; scanf("%d",&C); while(C--) {