zoukankan      html  css  js  c++  java
  • [洛谷1314]无序字母对

    本题地址: http://www.luogu.org/problem/show?pid=1341

    题目描述

    给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。

    输入输出格式

    输入格式:

    第一行输入一个正整数n。
    以下n行每行两个字母,表示这两个字母需要相邻。

    输出格式:

    输出满足要求的字符串。
    如果没有满足要求的字符串,请输出“No Solution”。
    如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案

    输入输出样例

    输入样例#1:

    4
    aZ
    tZ
    Xt
    aX

    输出样例#1:

    XaZtX
     

    说明

    【数据规模与约定】
    不同的无序字母对个数有限,n的规模可以通过计算得到。

    思路

      容易看出这是一个欧拉图。然而我思索了良久也不会写一个图的算法,只好用深搜和回溯写,又然而数据是在太水,竟然过了!

      P1:我用到了重边的判断。

      P2:要求按字典序输出,那么搜索的时候就从字典序最小的那一个开始搜索。

    var a:array['A'..'z','A'..'z'] of longint;
        du:array['A'..'z'] of longint;
        ans:array[0..100000] of char;
        n:longint;
    
    procedure dfs(u:char;tot:longint);
    var j:longint;k:char;
    begin
        ans[tot]:=u;
        if tot=n+1 then
            begin
                for j:=1 to n+1 do write(ans[j]);
                writeln;
                halt;
            end;
        for k:='A' to 'z' do
            if a[u,k]<>0 then
                begin
                    dec(a[u,k]);
                    dec(a[k,u]);
                    dfs(k,tot+1);
                    inc(a[k,u]);
                    inc(a[u,k]);
                    //回溯
                end;
    end;
    
    procedure change;
    begin
        fillchar(a,sizeof(a),0);
        fillchar(du,sizeof(du),0);
    end;
    
    procedure init;
    var i:longint;one,two:char;
    begin
        readln(n);
        for i:=1 to n do
            begin
                readln(one,two);
                inc(a[one,two]);
                inc(a[two,one]);
                inc(du[one]);
                inc(du[two]);
            end;
    end;
    
    procedure main;
    var x:char;one,two:char;
    begin
        for x:='A' to 'z' do
            if (du[x] mod 2=1) then
                begin
                    if two<>' ' then
                        begin
                            writeln('No Solution');
                            halt;
                        end;
                    if (one<>' ')and(two=' ') then two:=x;
                    if one=' ' then one:=x;
                end;
        if (one<>' ')and(two=' ') then
            begin
                writeln('No Solution');
                halt;
            end;
        //考虑到可能有重边的情况,one和two是两个备用字符串
        if (one=' ')and(two=' ') then
            begin
                for x:='A' to 'z' do
                    if du[x]<>0 then
                        break;
                dfs(x,1);
            end
        else
            if one>two then
                dfs(two,1)
            else
                dfs(one,1);
        //一切为了字典序
    end;
    
    begin
        change;
        init;
        main;
    end.
    View Code
  • 相关阅读:
    OK335xS-Android mkmmc-android-ubifs.sh hacking
    OK335xS-Android pack-ubi-256M.sh hacking
    OK335xS Ubuntu 12.04.1 版本 Android 开发环境搭建
    Qt Quick Hello World hacking
    Qt QML referenceexamples attached Demo hacking
    QT 5.4.1 for Android Ubuntu QtWebView Demo
    I.MX6 working note for high efficiency
    QT 5.4.1 for Android Windows环境搭建
    mkbootimg hacking
    Generate And Play A Tone In Android hacking
  • 原文地址:https://www.cnblogs.com/yangqingli/p/4743559.html
Copyright © 2011-2022 走看看