zoukankan      html  css  js  c++  java
  • 洛谷1341 无序字母对

    洛谷1341 无序字母对

    本题地址: 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的规模可以通过计算得到。

    【思路】

      欧拉道路。

      据每个相邻字母连无向边,那么题目中求得就是一条欧拉道路:不重复地遍历图中所有的边。

      需要注意的是:如果奇点个数不为0或2则无解,如果为0则从度数为2且序最小的节点开始,如果为2则从度数为奇且序最小的节点开始。

      另外需要注意答案的输出需要一个栈,还有push在程序中的位置。

    【代码】

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<vector>
     4 using namespace std;
     5 
     6 const int maxn = 100;
     7 
     8 int G[maxn][maxn];
     9 int cnt[maxn];
    10 
    11 int n,N=53;
    12 
    13 int vis[maxn][maxn];
    14 inline int calc(char c) {
    15     if(c>='A'&&c<='Z') return (int)c-'A';
    16     return (int)c-'a'+26;
    17 }
    18 inline char calc(int x) {
    19     if(x>=0 && x<26) return (char)x+'A';
    20     return (char)(x-26)+'a';
    21 }
    22 
    23 vector<int> ans;
    24 void euler(int u) {
    25     for(int v=0;v<N;v++) if(G[u][v]&&!vis[u][v]) {
    26         vis[u][v]=vis[v][u]=1;
    27         euler(v);
    28         ans.push_back(v);              //如是入栈 逆向输出 
    29     }
    30 }
    31 
    32 int main() {
    33     scanf("%d",&n);
    34     char a,b;
    35     for(int i=1;i<=n;i++) {
    36         cin>>a>>b;
    37         int x=calc(a),y=calc(b);
    38         G[x][y]=G[y][x]=1;
    39         cnt[x]++, cnt[y]++;
    40     }
    41     int tot=0,u1=1e8,u2=1e8;
    42     for(int i=0;i<N;i++) {
    43         if(cnt[i]&1) {
    44             tot++;
    45             u1=min(u1,i);
    46         }
    47         else if(cnt[i]) u2=min(u2,i);
    48     }
    49     if(tot!=0&&tot!=2) printf("No Solution
    ");
    50     else {
    51         int u;
    52         if(tot==0) u=u2; else u=u1;
    53         euler(u);
    54         ans.push_back(u);
    55         for(int i=ans.size()-1;i>=0;i--) cout<<calc(ans[i]);
    56         cout<<"
    ";
    57     }
    58     return 0;
    59 }
  • 相关阅读:
    文件权限命令
    复制、移动文件及目录命令
    创建、删除文件及目录命令
    绝对路径和相对路径
    查找文件命令
    链接命令
    文本搜索命令
    编辑器 vim
    有参装饰器与迭代器
    闭包函数与装饰器
  • 原文地址:https://www.cnblogs.com/lidaxin/p/4906907.html
Copyright © 2011-2022 走看看