如果发现广告等破坏行为,请尽量将条目恢复到较早的版本而不是把相应内容直接删除,谢谢合作。
URAL/1035
来自"NOCOW"
< URAL
首先,定义线就为边,正面的边,为正边,反面的边为负边。对于一个连通块,对于某个顶点,设k=abs(正边数-负边数),说明在这个点上,以该顶点作为开始端点,或结束端点的的针数至少为k,设count为此连通块的k总和,如果count=0那么ans+1,否则ans+count div 2(因为一个是头,一个是尾所以要除以2),不懂的可以看刘汝佳的黑书P274。
{$M 655360} program cao; const maxn=210; var d:array[0..maxn,0..maxn] of longint; visited,face1,face2,rear1,rear2:array[0..maxn,0..maxn] of boolean; a,b,c,e,f,g,h,i,j,k,l,n,m,p,q,count,ans:longint; ch:char; procedure init; begin readln(n,m); for i:=1 to n do begin for j:=1 to m do begin read(ch); if (ch=’X‘)or(ch=’\‘) then face1[i,j]:=true; if (ch=’X‘)or(ch=‘/’) then face2[i,j]:=true; end; readln; end; for i:=1 to n do begin for j:=1 to m do begin read(ch); if (ch=’X‘)or(ch=’\‘) then rear1[i,j]:=true; if (ch=’X‘)or(ch=‘/’) then rear2[i,j]:=true; end; readln; end; end; function search(i,j:longint):longint; var t:longint; begin if visited[i,j] then exit(0); visited[i,j]:=true; t:=d[i,j]; if (face1[i,j])or(rear1[i,j]) then inc(t,search(i-1,j-1)); if (face1[i+1,j+1])or(rear1[i+1,j+1]) then inc(t,search(i+1,j+1)); if (face2[i,j+1])or(rear2[i,j+1]) then inc(t,search(i-1,j+1)); if (face2[i+1,j])or(rear2[i+1,j]) then inc(t,search(i+1,j-1)); exit(t); end; procedure main; begin for i:=0 to n do for j:=0 to m do begin p:=0; q:=0; if face1[i,j] then inc(p); if face1[i+1,j+1] then inc(p); if face2[i,j+1] then inc(p); if face2[i+1,j] then inc(p); if rear1[i,j] then inc(q); if rear1[i+1,j+1] then inc(q); if rear2[i,j+1] then inc(q); if rear2[i+1,j] then inc(q); d[i,j]:=abs(p-q); if (p=0)and(q=0) then visited[i,j]:=true; end; ans:=0; for i:=0 to n do for j:=0 to m do if visited[i,j]=false then begin count:=search(i,j); if count=0 then inc(ans) else inc(ans,count shr 1); end; end; procedure print; begin writeln(ans); end; begin init; main; print; end.
华丽的分割线----------------------------------------------------------
饿,上面的标程好像在ural通不过去,会在第16个点栈溢出(stack overflow),仔细想想我认为是200*200的数据,dfs确实可能会导致系统栈溢出,所以我用了bfs来实现,通过了。基本思路一样。下面是我的程序(有点小乱)
const maxn=210; type rr=record x,y:longint; end; var ans,i,j,m,n,t,h,l:longint; len:array[0..maxn,0..maxn,0..3] of longint; p:array[0..maxn,0..maxn,0..8,0..3] of rr; bj:array[0..maxn,0..maxn] of boolean; c:char; dis:array[0..maxn,0..maxn] of longint; queue:array[1..maxn*maxn] of rr; father,sum:array[1..maxn*maxn] of longint; procedure dof(a:longint); begin inc(len[i,j+1,a]); p[i,j+1,len[i,j+1,a],a].x:=i+1; p[i,j+1,len[i,j+1,a],a].y:=j; inc(len[i+1,j,a]); p[i+1,j,len[i+1,j,a],a].x:=i; p[i+1,j,len[i+1,j,a],a].y:=j+1; end; procedure dos(a:longint); begin inc(len[i,j,a]); p[i,j,len[i,j,a],a].x:=i+1; p[i,j,len[i,j,a],a].y:=j+1; inc(len[i+1,j+1,a]); p[i+1,j+1,len[i+1,j+1,a],a].x:=i; p[i+1,j+1,len[i+1,j+1,a],a].y:=j; end; procedure bfs; var k,px,py:longint; begin repeat inc(h); px:=queue[h].x; py:=queue[h].y; for k:=1 to len[queue[h].x,queue[h].y,1] do if not bj[p[px,py,k,1].x,p[px,py,k,1].y] then begin inc(t); bj[p[px,py,k,1].x,p[px,py,k,1].y]:=true; father[t]:=h; queue[t]:=p[px,py,k,1]; end; for k:=1 to len[queue[h].x,queue[h].y,2] do if not bj[p[px,py,k,2].x,p[px,py,k,2].y] then begin inc(t); bj[p[px,py,k,2].x,p[px,py,k,2].y]:=true; father[t]:=h; queue[t]:=p[px,py,k,2]; end; until h=t; end; begin //读入 readln(n,m); fillchar(p,sizeof(p),0); fillchar(len,sizeof(len),0); for i:=1 to n do begin for j:=1 to m do begin read(c); if (c='/')or(c='X') then dof(1); if (c='\')or(c='X') then dos(1); end; readln; end; for i:=1 to n do begin for j:=1 to m do begin read(c); if (c='/')or(c='X') then dof(2); if (c='\')or(c='X') then dos(2); end; readln; end; //计算出每个点的正负边的差 fillchar(bj,sizeof(bj),false); ans:=0; for i:=1 to n+1 do for j:=1 to m+1 do dis[i,j]:=abs(len[i,j,1]-len[i,j,2]); t:=0; h:=0; //利用bfs求连通块 fillchar(father,sizeof(father),0); for i:=1 to n+1 do for j:=1 to m+1 do if (not bj[i,j])and(len[i,j,1]+len[i,j,2]<>0) then begin inc(t); queue[t].x:=i; queue[t].y:=j; bj[i,j]:=true; bfs; end; //计算 ans:=0; for i:=t downto 1 do begin if father[i]=0 then begin l:=(dis[queue[i].x,queue[i].y]+sum[i]) div 2; if l=0 then inc(l); ans:=ans+l; end else sum[father[i]]:=sum[father[i]]+dis[queue[i].x,queue[i].y]+sum[i]; end; writeln(ans); end. by Brad-Vegetable