Analysis
这道题如果说难的话只能是建立模型这一步吧。把每种标记看做一个点,骨牌就抽象成连接两点的一条边,有一点坑爹就是边有可能连接两个相同的点……建立了模型之后就是求无向图的欧拉路,dfs即可轻松解决。
Accepted Code
var
cnct:array[0..6,0..6] of longint;
cncted:array[0..6,0..6] of boolean;
deg:array[0..6] of longint;
used:array[1..200] of boolean;
ans,x,y:array[1..200] of longint;
tot,i,j,k,n,start,tmp:longint;
found,bo:boolean;
procedure dfs(u:longint);
var
i:longint;
begin
if tot=n*2 then
begin
found:=true;
exit;
end;
for i:=0 to 6 do
if cnct[u,i]>0 then
begin
dec(cnct[u,i]);
dec(cnct[i,u]);
ans[tot+1]:=u;
ans[tot+2]:=i;
tot:=tot+2;
dfs(i);
if found then
break;
dec(tot,2);
inc(cnct[u,i]);
inc(cnct[i,u]);
end;
end;
function check(i,j:longint):boolean;
var
bo:boolean;
begin
bo:=((ans[2*i-1]=x[j]) and (ans[2*i]=y[j])) or ((ans[2*i]=x[j]) and (ans[2*i-1]=y[j]));
check:=bo;
end;
procedure print(i,j:longint);
begin
write(j);
if x[j]=ans[2*i-1] then
writeln(' +')
else
writeln(' -');
end;
begin
fillchar(cnct,sizeof(cnct),0);
fillchar(deg,sizeof(deg),0);
fillchar(cncted,sizeof(cncted),0);
readln(n);
for i:=1 to n do
begin
readln(x[i],y[i]);
inc(cnct[x[i],y[i]]);
inc(cnct[y[i],x[i]]);
cncted[x[i],y[i]]:=true;
cncted[y[i],x[i]]:=true;
inc(deg[x[i]]);
inc(deg[y[i]]);
start:=y[i];
end;
tmp:=0;
for i:=0 to 6 do
if odd(deg[i]) then
begin
inc(tmp);
start:=i;
end;
for k:=0 to 6 do
for i:=0 to 6 do
for j:=0 to 6 do
if cncted[i,k] and cncted[k,j] then
cncted[i,j]:=true;
bo:=true;
for i:=0 to 6 do
for j:=0 to 6 do
if (deg[i]>0) and (deg[j]>0) then
bo:=bo and cncted[i,j];
if (tmp>2) or not bo then
writeln('No solution')
else
begin
tot:=0;
found:=false;
dfs(start);
fillchar(used,sizeof(used),false);
for i:=1 to n do
begin
for j:=1 to n do
if not used[j] and check(i,j) then
begin
print(i,j);
used[j]:=true;
break;
end;
end;
end;
end.