会做jsoi那道game,这题就非常简单了吧
我们考虑空格的移动,显然,初始与空格位置距离为奇数的黑棋和距离为偶数的白棋并没有什么用,
空格不会移到那,我们直接把他们当作障碍,其他点我们当作可移动区域
这不就和game那道题一样了吗,只不过这题不问棋子放哪
而是给定棋子位置,问当前是否是先手必胜
(错误操作就是指当前是先手必胜而移动一格还是先手必胜的操作)
我们对图重新黑白染色,做二分图匹配,显然,棋子在一定能被匹配的点上时,是先手必胜
证明类似game,因为棋子在一定在一定能被匹配的点上,我们第一步走向匹配点
下一步对方要么不能走,要么走一条非匹配边,那所到达的点,一定是匹配了的
否则,一开始的点就不一定在匹配,与假设矛盾,所以最后走的一条边一定是匹配边得证
至于怎么找一定能被匹配的点,我们做完二分图匹配后,如果这个点匹配了,那么我们删掉这个点,从这个点配对的点出发看是否能找到增广路即可
1 const dx:array[1..4] of longint=(0,0,1,-1); 2 dy:array[1..4] of longint=(1,-1,0,0); 3 4 type node=record 5 po,next:longint; 6 end; 7 8 var e:array[0..4010] of node; 9 v:array[0..2010] of boolean; 10 b:array[0..50,0..50] of longint; 11 a:array[0..50,0..50] of char; 12 mat,p,c:array[0..2010] of longint; 13 t,xx,yy,i,n,m,j,k,len,x,y,ans:longint; 14 f1,f2:boolean; 15 16 procedure add(x,y:longint); 17 begin 18 inc(len); 19 e[len].po:=y; 20 e[len].next:=p[x]; 21 p[x]:=len; 22 end; 23 24 function dfs(x:longint):boolean; 25 var i,y:longint; 26 begin 27 v[x]:=true; 28 i:=p[x]; 29 while i<>0 do 30 begin 31 y:=e[i].po; 32 if not v[y] and (mat[y]<>-1) then 33 begin 34 v[y]:=true; 35 if (mat[y]=0) or dfs(mat[y]) then 36 begin 37 mat[y]:=x; 38 mat[x]:=y; 39 exit(true); 40 end; 41 end; 42 i:=e[i].next; 43 end; 44 exit(false); 45 end; 46 47 function check:boolean; 48 var j,k:longint; 49 begin 50 k:=b[x,y]; 51 j:=mat[k]; 52 mat[j]:=0; 53 mat[k]:=-1; 54 if j=0 then exit(false) 55 else begin 56 fillchar(v,sizeof(v),false); 57 exit(not dfs(j)); 58 end; 59 end; 60 61 begin 62 readln(n,m); 63 for i:=1 to n do 64 begin 65 for j:=1 to m do 66 begin 67 read(a[i,j]); 68 if a[i,j]='.' then 69 begin 70 x:=i; 71 y:=j; 72 a[i,j]:='X'; 73 end; 74 end; 75 readln; 76 end; 77 for i:=1 to n do 78 for j:=1 to m do 79 if (a[i,j]='O') xor ((abs(i-x)+abs(j-y)) mod 2=0) then 80 begin 81 inc(t); 82 b[i,j]:=t; 83 end; 84 85 for i:=1 to n do 86 for j:=1 to m do 87 if b[i,j]>0 then 88 begin 89 for k:=1 to 4 do 90 begin 91 xx:=i+dx[k]; 92 yy:=j+dy[k]; 93 if b[xx,yy]>0 then add(b[i,j],b[xx,yy]); 94 end; 95 end; 96 97 for i:=1 to t do 98 if mat[i]=0 then 99 begin 100 fillchar(v,sizeof(v),false); 101 dfs(i); 102 end; 103 104 readln(k); 105 for i:=1 to k do 106 begin 107 f1:=check; 108 readln(x,y); 109 f2:=check; 110 if f1 and f2 then 111 begin 112 inc(ans); 113 c[ans]:=i; 114 end; 115 readln(x,y); 116 end; 117 writeln(ans); 118 for i:=1 to ans do 119 writeln(c[i]); 120 end.