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
  • 相关阅读:
    java 各个文件夹的含义
    对称加密 & 非对称加密
    leetcode 155 最小栈
    leetcode 53 最大自序列和
    leetcode 146 LRU 缓存机制
    notebook 开启 有限元学习
    leetcode 232 用栈实现队列
    LINUX装机问题:无法使用“Ctrl+Alt+[F1~F6]”快捷键切换到终端
    JAVA笔记4-static关键字
    C++构造函数、析构函数、虚析构函数
  • 原文地址:https://www.cnblogs.com/yangqingli/p/4743559.html
Copyright © 2011-2022 走看看