[SGU]101. Domino

来源:互联网 发布:中科院研究员待遇知乎 编辑:程序博客网 时间:2024/05/01 00:36

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.