【GDOI2016模拟3.11】游戏

Description

这里写图片描述

Input

这里写图片描述

Output

这里写图片描述

Sample Input

2 2
RL
LR
2 2
RR
RR

Sample Output

LOSE
WIN

Data Constraint

这里写图片描述

题解

这道题调了我好久(不要问我为什么水题要想这么久)。
看到题目是游戏,第一想法肯定是SG函数(过来人的经验之谈)。
然而,由于讲题人刘某的表述,使我在错误的革命道路上一错再错。
后来,我发现:
对于这道题,我们把一个棋盘,拆分成两个互相独立的棋盘,因为只有斜着的变化,所以两个棋盘是互相独立的(相当于国际象棋里的黑格和白格)。
接着,我们把棋盘斜过来,每一个操作:
‘R’即横着切成两半,‘L’即竖着切成两半,‘X’即横竖着切成四块。每切成块又互相独立(因为碰到非活动格即停止拓展)。
那么,我们可以递归搜索+记忆化剪枝。
对于每一个区间,我们枚举每一个点,将其分割开来,sg值异或一下,再对于所有的sg值,取个mex1就好了。
code:

uses math;
var
        n,m,i,j,x,y,mx1,my1,sg,mx2,my2:longint;
        a:array[0..20,0..20]of char;
        x1,x2:array[0..500,0..500,1..2]of longint;
        g:array[0..20,0..20,0..20,0..20,1..2]of longint;
function dg(stx,sty,enx,eny,tt:longint):longint;
var
        i,j,sgg,x,y,o:longint;
        t:array[0..200]of longint;
begin
        fillchar(t,sizeof(t),0);
        if (stx>enx)or(sty>eny) then
                exit(0);
        if g[stx,sty,enx,eny,tt]<>-1 then
                exit(g[stx,sty,enx,eny,tt]);
        o:=0;
        for i:=stx to enx do
                for j:=sty to eny do
                begin
                        if tt=1 then
                        begin
                                x:=x1[i,j,1];
                                y:=x1[i,j,2];
                        end
                        else
                        begin
                                x:=x2[i,j,1];
                                y:=x2[i,j,2];
                        end;
                        if (x<>0)and(y<>0) then
                                inc(o);
                end;
        if o=1 then
        begin
                g[stx,sty,enx,eny,tt]:=1;
                exit(1);
        end;
        sgg:=0;
        for i:=stx to enx do
        begin
                for j:=sty to eny do
                begin
                        if tt=1 then
                        begin
                                x:=x1[i,j,1];
                                y:=x1[i,j,2];
                        end
                        else
                        begin
                                x:=x2[i,j,1];
                                y:=x2[i,j,2];
                        end;
                        if (x=0)or(y=0) then
                                continue;
                        inc(o);
                        case a[x,y] of
                                'R':sgg:=dg(stx,sty,i-1,eny,tt) xor dg(i+1,sty,enx,eny,tt);
                                'L':sgg:=dg(stx,sty,enx,j-1,tt) xor dg(stx,j+1,enx,eny,tt);
                                'X':sgg:=dg(stx,sty,i-1,j-1,tt) xor dg(stx,j+1,i-1,eny,tt) xor dg(i+1,sty,enx,j-1,tt) xor dg(i+1,j+1,enx,eny,tt);
                        end;
                        t[sgg]:=1;
                end;
        end;
        if o=1 then
        begin
                g[stx,sty,enx,eny,tt]:=1;
                exit(1);
        end;
        for i:=0 to 200 do
                if t[i]=0 then
                begin
                        g[stx,sty,enx,eny,tt]:=i;
                        exit(i);
                end;
end;
begin
        while not eof do
        begin
                readln(n,m);
                fillchar(x1,sizeof(x1),0);
                fillchar(x2,sizeof(x2),0);
                fillchar(g,sizeof(g),255);
                my1:=0;
                my2:=0;
                x:=1;
                y:=n div 2;
                if n mod 2=1 then
                        inc(y);
                x1[x,y,1]:=1;
                x1[x,y,2]:=1;
                mx1:=1;
                my1:=1;
                for i:=1 to n do
                begin
                        for j:=1 to m do
                        begin
                                read(a[i,j]);
                                if (j+i) mod 2=0 then
                                begin
                                        if (i=1)and(j=1) then
                                                continue;
                                        x:=(i+j) div 2;
                                        y:=(n-i+j+1) div 2;
                                        mx1:=max(mx1,x);
                                        my1:=max(my1,y);
                                        x1[x,y,1]:=i;
                                        x1[x,y,2]:=j;
                                end
                                else
                                begin
                                        x:=(i+j) div 2;
                                        y:=(n-i+j+1) div 2;
                                        mx2:=max(mx2,x);
                                        my2:=max(my2,y);
                                        x2[x,y,1]:=i;
                                        x2[x,y,2]:=j;
                                end;
                        end;
                        readln;
                end;
                sg:=dg(1,1,mx1,my1,1) xor dg(1,1,mx2,my2,2);
                if sg=0 then
                        writeln('LOSE')
                else
                        writeln('WIN');
        end;
end.     

  1. mex(u)表示集合内没有出现过的最小自然数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值