NOI 兔兔与蛋蛋的游戏

 二维的一个最大匹配


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.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值