NOI 兔兔與蛋蛋的遊戲

2021-06-07 19:55:00 字數 3938 閱讀 5218

二維的乙個最大匹配

program game;

type rec=record x,y:longint; end;

const numm:rec=(x:0;y:0);

dx:array[1..4]of integer=(0,1,0,-1);

dy:array[1..4]of integer=(1,0,-1,0);

var

link:array[0..41,0..41]of rec;

yy:array[0..41,0..41]of boolean;

ans:array[0..400]of longint;

a:array[0..41,0..41]of boolean;

b:array[0..41,0..41]of byte;

n,m:longint;

function find(x,y:longint):boolean; var r:byte; tmp:^rec;

begin

for r:=1 to 4 do if (not yy[x+dx[r]][y+dy[r]])and(a[x+dx[r]][y+dy[r]]) then begin

tmp:=@link[x+dx[r]][y+dy[r]];yy[x+dx[r]][y+dy[r]]:=true;

if ((tmp^.x=0)and(tmp^.y=0))or(find(tmp^.x,tmp^.y)) then begin

tmp^.x:=x;tmp^.y:=y;exit(true);

end;

end; exit(false);

end;

function win(x,y:longint):boolean; var tmp,i,j:longint;

begin

tmp:=0;

a[x][y]:=true;

for i:=1 to n do for j:=1 to m do

if ((i xor j) and 1=1)and a[i][j] then begin

fillchar(yy,sizeof(yy),false);

if find(i,j) then inc(tmp);

end;

fillchar(link,sizeof(link),0);

a[x][y]:=false;

for i:=1 to n do for j:=1 to m do

if ((i xor j) and 1=1) and a[i][j] then begin

fillchar(yy,sizeof(yy),false);

if find(i,j) then dec(tmp);

end;

fillchar(link,sizeof(link),0);

exit(tmp<>0);

end;

var i,j,x,y,k:longint; ch:char; now:boolean;

begin

assign(input,'input.txt');reset(input);

assign(output,'output.txt');rewrite(output);

readln(n,m);

for i:=1 to n do begin

for j:=1 to m do begin

read(ch); case ch of

'.':begin

x:=i; y:=j;

k:=(i xor j)and 1;

end;

'o':b[i][j]:=0;

'x':b[i][j]:=1;

end;

end; readln;

end;

for i:=1 to n do

for j:=1 to m do

a[i][j]:=((i xor j xor k)and 1 xor b[i][j]=1);

readln(k);

now:=win(x,y);

a[x,y]:=false;

for k:=1 to k do begin

readln(x,y);

if now and find(x,y) then begin

inc(ans[0]); ans[ans[0]]:=k;

end;a[x,y]:=false;

readln(x,y);

now:=find(x,y);a[x,y]:=false;

end;

writeln(ans[0]);

for i:=1 to ans[0] do writeln(ans[i]);

close(input);close(output);

end.

樸素的做法

program game;

const

dx:array[1..4]of shortint=(1,0,-1,0);

dy:array[1..4]of shortint=(0,1,0,-1);

var ans:array[0..400]of longint;

a:array[0..41,0..41]of boolean;

b:array[1..40,1..40]of byte;

function find(const x,y:byte):boolean;

var r:byte;

begin

find:=false;

a[x,y]:=false;

for r:=1 to 4 do

if a[x+dx[r]][y+dy[r]] then

if not find(x+dx[r],y+dy[r]) then begin

find:=true;

break;

end;

a[x,y]:=true;

end;

var n,m,i,j,k,x,y:longint; ch:char; now:boolean;

begin

assign(input,'input.txt');reset(input);

assign(output,'output.txt');rewrite(output);

readln(n,m);

for i:=1 to n do begin

for j:=1 to m do begin

read(ch); case ch of

'.':begin

x:=i; y:=j;

k:=(i xor j)and 1;

end;

'o':b[i][j]:=0;

'x':b[i][j]:=1;

end;

end; readln;

end;

for i:=1 to n do

for j:=1 to m do

a[i][j]:=((i xor j xor k)and 1 xor b[i][j]=1);

readln(k);

now:=find(x,y);a[x,y]:=false;

for k:=1 to k do begin

readln(x,y);a[x][y]:=false;

if now and find(x,y) then begin

inc(ans[0]); ans[ans[0]]:=k;

end;a[x][y]:=false;

readln(x,y);

a[x][y]:=false;

now:=find(x,y);

a[x][y]:=false;

end;

writeln(ans[0]);

for i:=1 to ans[0] do writeln(ans[i]);

close(input);close(output);

end.

NOI2011 兔兔與蛋蛋遊戲

傳送門 直接博弈論dfs可以得到75分 然鵝我博弈論學的很pie include define ll long long define inf 10000 using namespace std intread while s 0 s 9 return x f char s 45 int lr ud...

Noi2011 兔兔與蛋蛋

題目 題解容易想到空格移動的路徑是不會自交的。因為空格移動的路徑是黑白棋相間的 所以對棋盤進行黑白染色,建立二分圖 如果黑白兩格上的棋子不一樣則可以連邊 如果乙個人 a 將空格移入了乙個在最大匹配內的點,那麼它的對手 b 就可以沿著匹配邊前進 否則就相當於找到了一條新的匹配邊 而a只能沿著非匹配邊前...

NOI2011 洛谷 兔兔與蛋蛋遊戲

初見安 這裡是傳送門 洛谷p1971 noi2011 兔兔與蛋蛋遊戲 這種題啊 就只能多悟,才能看到了就知道怎麼做 bushi。看題目的操作 每次交替移動黑白棋子。然後就可以想到二分圖了 什麼鬼。空白格仔從初始到終點走的路徑上的格仔都是與之交換過的,並且黑白相間,該路徑與以前走過的路徑不可能有交點。...