[SGU]101. Domino

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.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值