首页 > 代码库 > BZOJ1298骰子的学问
BZOJ1298骰子的学问
题解:
把ai认为是i的父亲,使其连边,那么题目给出的关系构成了一个基环树森林。
对于在环外、指向环的边(即“树”的部分),使骰子的每一个面都比其父亲大。
观察1、4样例可以发现一个构造方式:对于一个大小为n环,从第一个点开始,逆着父亲边放入1~n;再从第一个点在环上的儿子开始,逆着父亲边以此放入n+1~2*n,知道放满n*m个数。
但是这个构造法在样例3中失败了。事实上,可以证明,只有在像样例3这种环大小为3,骰子面数为4的情况下,该方法会失效。对于这种情况,进行特判。
注意环大小为2或是m<=2的情况,一定无法构造。
代码:
const bb:array[1..12]of longint=(1,2,4,3,7,5,10,8,6,11,9,12); var i,j,k,l,n,m,cnt:longint; fa,a,b,c:array[0..1001]of longint; d:array[0..1001,0..1001]of longint; procedure ss2(x:longint); var i:longint; begin if a[x]<2 then begin for i:=1 to m do begin inc(cnt); d[x,i]:=cnt; end; a[x]:=2; end; i:=c[x]; while i>0 do begin if a[i]<2 then ss2(i); i:=b[i]; end; end; procedure ss(x:longint); var i,j,k,l,xx:longint; begin a[x]:=1; x:=fa[x]; while a[x]=0 do begin a[x]:=1; x:=fa[x]; end; k:=1; xx:=fa[x]; a[x]:=2; while x<>xx do begin inc(k); a[xx]:=2; xx:=fa[xx]; end; if k<=2 then begin writeln(0); halt; end; if(k=3)and(m=4)then begin for i:=1 to 12 do begin d[x,1+((i-1)div 3)]:=bb[i]; x:=fa[x]; end; end else begin for i:=1 to m do begin l:=cnt+k; for j:=1 to k do begin d[x,i]:=l; dec(l); if j<>k then x:=fa[x]; end; cnt:=cnt+k; end; end; for i:=1 to k do begin ss2(x); x:=fa[x]; end; end; begin readln(n,m); for i:=1 to n do begin read(fa[i]); b[i]:=c[fa[i]]; c[fa[i]]:=i; end; for i:=1 to n do if a[i]=0 then ss(i); for i:=1 to n do begin for j:=1 to m do write(d[i,j],‘ ‘); writeln; end; end.
BZOJ1298骰子的学问
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。