$ \color{#0066ff}{ 题目描述 }$

n*m的格子,每个格子有字符'L','R',X',初始可以选择所有格子.

当选了 'L'的格子时,当前格子左下右上这条线上所有点不能选;

当选了 'R'的格子时,当前格子右下左上这条线上所有点不能选;

当选了 'X'的格子时,就是相当于同时选了'L','R';

如果不是最后选的输出'WIN',否则输出'LOSE'

\(\color{#0066ff}{输入格式}\)

第一行两个正整数 \(n,m\) 表示网格大小

接下来是格子

\(\color{#0066ff}{输出格式}\)

如果不是最后选的输出'WIN',否则输出'LOSE'

\(\color{#0066ff}{输入样例}\)

2 2
RL
LR 2 2
RR
RR

\(\color{#0066ff}{输出样例}\)

LOSE

WIN

\(\color{#0066ff}{数据范围与提示}\)

1<=n,m<=20

\(\color{#0066ff}{题解}\)

对于对角线的切割,我们不好处理,考虑旋转坐标系

然后,方格就形成了一个菱形,每次我们或横切或纵切,或者一起

然后发现,对这个菱形黑白染色,黑和白是不会互相影响的!于是我们就分成了2个游戏

我用坐标范围来表示当前的状态,每次枚举所有格子,转移到两个或四个游戏,异或起来作为后继状态

直接SG定理即可

#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const int maxn = 55;
int n, m;
int sg[maxn][maxn][maxn][maxn][2];
char mp[maxn][maxn];
bool vis[1002020];
int work(int xmin, int xmax, int ymin, int ymax, int tp) {
if(xmin > xmax || ymin > ymax) return 0;
int &now = sg[xmin][xmax][ymin][ymax][tp];
if(~now) return now;
now = 0;
for(int x = 1; x <= n; x++)
for(int y = 1; y <= m; y++)
if(((x + y) & 1) == tp) {
int xx = x + y, yy = x - y + m;
if(xmin <= xx && xx < xmax && ymin <= yy && yy < ymax) {
if(mp[x][y] == 'L') work(xmin, xx, ymin, ymax, tp), work(xx + 1, xmax, ymin, ymax, tp);
if(mp[x][y] == 'R') work(xmin, xmax, ymin, yy, tp), work(xmin, xmax, yy + 1, ymax, tp);
if(mp[x][y] == 'X') work(xmin, xx, ymin, yy, tp), work(xmin, xx, yy + 1, ymax, tp),
work(xx + 1, xmax, ymin, yy, tp), work(xx + 1, xmax, yy + 1, ymax, tp);
}
}
for(int x = 1; x <= n; x++)
for(int y = 1; y <= m; y++)
if(((x + y) & 1) == tp) {
int xx = x + y, yy = x - y + m;
if(xmin <= xx && xx < xmax && ymin <= yy && yy < ymax) {
if(mp[x][y] == 'L') vis[sg[xmin][xx][ymin][ymax][tp] ^ sg[xx + 1][xmax][ymin][ymax][tp]] = true;
if(mp[x][y] == 'R') vis[sg[xmin][xmax][ymin][yy][tp] ^ sg[xmin][xmax][yy + 1][ymax][tp]] = true;
if(mp[x][y] == 'X') vis[sg[xmin][xx][ymin][yy][tp] ^ sg[xmin][xx][yy + 1][ymax][tp] ^
sg[xx + 1][xmax][ymin][yy][tp] ^ sg[xx + 1][xmax][yy + 1][ymax][tp]] = true;
}
}
while(vis[now]) now++;
for(int x = 1; x <= n; x++)
for(int y = 1; y <= m; y++)
if(((x + y) & 1) == tp) {
int xx = x + y, yy = x - y + m;
if(xmin <= xx && xx < xmax && ymin <= yy && yy < ymax) {
if(mp[x][y] == 'L') vis[sg[xmin][xx][ymin][ymax][tp] ^ sg[xx + 1][xmax][ymin][ymax][tp]] = false;
if(mp[x][y] == 'R') vis[sg[xmin][xmax][ymin][yy][tp] ^ sg[xmin][xmax][yy + 1][ymax][tp]] = false;
if(mp[x][y] == 'X') vis[sg[xmin][xx][ymin][yy][tp] ^ sg[xmin][xx][yy + 1][ymax][tp] ^
sg[xx + 1][xmax][ymin][yy][tp] ^ sg[xx + 1][xmax][yy + 1][ymax][tp]] = false;
}
}
return now;
}
char getch() {
char ch;
while(!isalpha(ch = getchar()));
return ch;
}
int main() {
n = in(), m = in();
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
mp[i][j] = getch();
memset(sg, -1, sizeof sg);
puts(work(2, n + m + 3, 1, n + m + 3, 0) ^ work(1, n + m + 3, 1, n + m + 3, 1)? "WIN" : "LOSE");
return 0;
}

CF138D World of Darkraft的更多相关文章

  1. [codeforces464D]World of Darkraft - 2 概率期望

    D. World of Darkraft - 2 time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  2. CF464D World of Darkraft - 2

    Roma 在游戏"World of Darkraft"(理论上应该是 World of darkcraft,MineCraft 的一个版本)找到一个新角色. \(\mathrm{R ...

  3. Codeforces 138D World of Darkraft

    有一个n*m 的棋盘,每个点上标记了L,R,X 中的一个每次能选择一个没有被攻击过的点(i,j),从这个点开始发射线,射线形状为:1. 若字符是 L,向左下角和右上角发,遇到被攻击过的点就停下来2. ...

  4. 【Codeforces 464D】World of Darkraft - 2

    Codeforces 464 D 首先我们知道这K个装备是互不干扰的,就是说如果一个装备升级了或者卖掉了,不会对其它装备的挣到的钱产生任何影响.所以我们就考虑单独处理某一个装备挣到的钱. 那么就设\( ...

  5. Codeforces 464D-World of Darkraft - 2

    题意 有 \(n\) 个怪兽,\(k\) 种装备.最开始每个装备的等级都是 1 .每打完一个怪兽就会随机掉落一个装备. 随机的方式是,先等概率随机一个装备种类,设当前这个装备的等级为 \(t\) ,那 ...

  6. Codeforces 138D World of Darkraft(Multi-Nim)

    [题目链接] http://codeforces.com/problemset/problem/138/D [题目大意] H*W的棋盘中每个点都是L.R.X三者之一,两人轮流选一个点, 若为L则向左下 ...

  7. World of Darkraft(codeforces 138D)

    题意:有一个 n × m 的棋盘,每个点上标记了 L; R; X 中的一个 每次能选择一个没有被攻击过的点 (i; j),从这个点开始发射线,射线形状为: 1. 若字符是 L,向左下角和右上角发,遇到 ...

  8. Codeforces 1321E World of Darkraft: Battle for Azathoth

    题意 有\(n\)个武器,第\(i\)个武器攻击力为\(a_i\),价值\(ca_i\). 有\(m\)个防具,第\(i\)个防具防御力为\(b_i\),价值\(cb_i\). 有\(p\)个怪,第\ ...

  9. CF1320C World of Darkraft: Battle for Azathoth

    线段树 又是熟悉的感觉,又是E题写完了,没调完,不过还好上了紫 CF1295E 可以发现可以打败怪兽的关系类似二维偏序 那么首先考虑第一维(武器)以攻击值($a_{i}$)进行排序 把所有的怪兽以防御 ...

随机推荐

  1. [原创]Spring Boot + Mybatis 简易使用指南(二)多参数方法支持 与 Joda DateTime类型支持

    前言 今天在开发练习项目时遇到两个mybatis使用问题 第一个问题是mapper方法参数问题,在参数大于一个时,mybatis不会自动识别参数命名 第二个问题是Pojo中使用Joda DateTim ...

  2. 结合spring 实现自定义注解

    注解类 import java.lang.annotation.*; /** * Created by Administrator on 2016/6/28. */ //ElementType.MET ...

  3. 23-从零玩转JavaWeb-单例设计模式

    一.什么是设计模式 二.什么是单例设计模式 三.单例设计模式特点 四.单例设计模式优点 五.单例设计模式实现步骤   六.什么是工具类  

  4. spark源码阅读之network(1)

    spark将在1.6中替换掉akka,而采用netty实现整个集群的rpc的框架,netty的内存管理和NIO支持将有效的提高spark集群的网络传输能力,为了看懂这块代码,在网上找了两本书看< ...

  5. Socket接口原理及用C#语言实现

    首先从原理上解释一下采用Socket接口的网络通讯,这里以最常用的C/S模式作为范例,首先,服务端有一个进程(或多个进程)在指定的端口等待客户来连接,服务程序等待客户的连接信息,一旦连接上之后,就可以 ...

  6. jQuery对象与DOM对象及互相转化

    <p id=‘’hello”></p> 普通处理,通过标准JavaScript处理: var p = document.getElementById('hello'); p.i ...

  7. Linux下安装memcache PHP扩展

    [root@centos memcache-2.2.4]# wget http://pecl.php.net/get/memcache-2.2.4.tgz [root@centos memcache- ...

  8. Linux 下安装Yaf扩展

    1.在官网下载了yaf扩展包 yaf-3.0.3.tgz 2.开始安装yaf扩展 tar zxvf yaf-3.0.3.tgz cd yaf-3.0.3 phpize ./configure --wi ...

  9. 编写高质量代码改善C#程序的157个建议——建议15: 使用dynamic来简化反射实现

    建议15: 使用dynamic来简化反射实现 dynamic是Framework 4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译器默认dy ...

  10. 学习如何用VS2010创建ocx控件

    1参考文章 (1)这一篇将使用vc创建ocx控件:http://blog.csdn.net/jiadelin/article/details/2917225 (2)这一篇文章有关vs2010创建act ...