您的位置:首页 > 其它

【欧拉回路+高斯消元】超级翻转

2010-11-10 21:53 288 查看
一道非常好的综合题!

因为有多组数据,要注意的是数组清零。

利用欧拉回路优美的性质构造异或方程组,详见刘书。

program ex1;
var
l,u,a,b:array[0..20,0..20] of longint;
f:array[0..600,0..600] of boolean;
p,next,d,o,g,ans:array[-2000..2000] of longint;
t,n,i,j,k,v,sx,sy,ss,tx,ty,tt,tot,task:longint;
ok:boolean;
procedure link(a,b:longint);
begin
inc(t);next[t]:=d[a];d[a]:=t;p[t]:=b;
next[-t]:=d[b];d[b]:=-t;p[-t]:=a;
end;
procedure dfs(i:longint);var j,k:longint;
begin
k:=d[i];j:=p[k];
while k<>0 do begin
if o[abs(k)]>0 then begin
dec(o[abs(k)]);dfs(j);
end;
k:=next[k];j:=p[k];
end;
inc(ans[0]);ans[ans[0]]:=i;
end;
procedure add(a,b,c,d:longint;e:boolean);
begin
fillchar(f[t+1],sizeof(f[0]),0);
inc(t);f[t,0]:=e;
if a<>0 then f[t,a]:=true;
if b<>0 then f[t,b]:=true;
if c<>0 then f[t,c]:=true;
if d<>0 then f[t,d]:=true;
end;
begin
assign(input,'turn.in');reset(input);
assign(output,'turn.out');rewrite(output);
readln(task);
for task:=1 to task do begin
readln(n);tot:=0;t:=0;
fillchar(d,sizeof(d),0);
fillchar(l,sizeof(l),0);
fillchar(u,sizeof(u),0);
for i:=1 to n do
for j:=1 to n do read(a[i,j]);
for i:=1 to n+1 do
for j:=1 to n+1 do begin
inc(tot);b[i,j]:=tot;
if i>1 then begin
link(b[i,j],b[i-1,j]);
u[i,j]:=t;
end;
if j>1 then begin
link(b[i,j],b[i,j-1]);
l[i,j]:=t;
end;
end;
readln(sx,sy);tot:=t;ok:=false;
for tx:=1 to n+1 do
for ty:=1 to n+1 do if not ok then begin
ss:=b[sx,sy];tt:=b[tx,ty];
t:=0;
if ss=tt then
add(l[sx,sy],u[sx,sy],l[sx,sy+1],u[sx+1,sy],false)
else begin
add(l[sx,sy],u[sx,sy],l[sx,sy+1],u[sx+1,sy],true);
add(l[tx,ty],u[tx,ty],l[tx,ty+1],u[tx+1,ty],true);
end;
for i:=1 to n+1 do
for j:=1 to n+1 do if (b[i,j]<>ss)and(b[i,j]<>tt) then
add(l[i,j],u[i,j],l[i,j+1],u[i+1,j],false);
for i:=1 to n do
for j:=1 to n do
add(l[i+1,j+1],u[i+1,j+1],l[i,j+1],u[i+1,j],a[i,j]=1);
j:=1;ok:=true;
for i:=1 to tot do begin
for k:=j to t do if f[k,i] then break;
if f[k,i] then begin
f[0]:=f[j];f[j]:=f[k];f[k]:=f[0];
for k:=j+1 to t do if f[k,i] then begin
for v:=i to tot do f[k,v]:=f[k,v] xor f[j,v];
f[k,0]:=f[k,0] xor f[j,0];
end;
g[i]:=j;inc(j);
end else g[i]:=0;
end;
for j:=j to t do if f[j,0] then begin
ok:=false;
for i:=1 to tot do if f[j,i] then ok:=true;
if not ok then break;
end;
if not ok then continue;
for i:=tot downto 1 do
if g[i]=0 then o[i]:=2
else begin
o[i]:=2-ord(f[g[i],0]);
for j:=1 to g[i]-1 do
if f[j,i] then f[j,0]:=f[j,0]xor f[g[i],0];
end;
ans[0]:=0;dfs(ss);
for i:=ans[0]-1 downto 1 do begin
if ans[i]+1=ans[i+1] then write('L') else
if ans[i]-1=ans[i+1] then write('R') else
if ans[i]>ans[i+1] then write('D') else write('U');
end;
writeln;break;
end;
if not ok then writeln('No Solution!');
end;
close(input);close(output);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: