【GDOI2016模擬3.11】遊戲
阿新 • • 發佈:2019-01-23
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值,取個mex 1就好了。
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.
- mex(u)表示集合內沒有出現過的最小自然數。 ↩