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

一道非常好的综合题!

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

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

 

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. 

你可能感兴趣的:(c,input,output)