二維的乙個最大匹配
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。看題目的操作 每次交替移動黑白棋子。然後就可以想到二分圖了 什麼鬼。空白格仔從初始到終點走的路徑上的格仔都是與之交換過的,並且黑白相間,該路徑與以前走過的路徑不可能有交點。...