码迷,mamicode.com
首页 > 其他好文 > 详细

洛谷1341 无续字母对

时间:2017-10-24 20:55:17      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:==   ret   个数   div   out   pre   情况   clu   区分大小写   

题目描述

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

输入输出格式

输入格式:

 

第一行输入一个正整数n。

以下n行每行两个字母,表示这两个字母需要相邻。

 

输出格式:

 

输出满足要求的字符串。

如果没有满足要求的字符串,请输出“No Solution”。

如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案

 

输入输出样例

输入样例#1: 
4
aZ
tZ
Xt
aX
输出样例#1: 
XaZtX
 
这道题是欧拉回路?差不多吧。先判断每个点的度数,如果基数点的个数不为2或0,就是无解了。然后跑图就好了。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int g[55][55], deg[55];
vector<int > ans;
int tonum(char x){                                               //字符转为数字
    if(x<=Z) return x-A+1;
    return x-a+1+26;
}
char tochar(int x){                                                //数字转字符
    if(x<=26) return x+A-1;
    return x+a-1-26;
}
void dfs(int here){                                                //从单点开始的欧拉回/链路dfs
    for(int i=1;i<=52;i++)                                  //确保字典序
        if(g[here][i]){
            g[here][i]=0;                                 //删除边线
            g[i][here]=0;
            dfs(i);
        }
    ans.push_back(here);                                   //添加顶点到回/链路中
}
int main(){
    int n, u1=100, u2=100, cnt=0;
    cin>>n;
    for(int i=1;i<=n;i++){                                       //建图
        char x, y;
        cin>>x>>y;
        if(!g[tonum(x)][tonum(y)]){
            g[tonum(x)][tonum(y)]=1;
            g[tonum(y)][tonum(x)]=1;
            deg[tonum(x)]++;                              //出入度统计
            deg[tonum(y)]++;
        }
    }
    for(int i=1;i<=52;i++)                                                                     //统计奇点数
        if(deg[i]&1){                          
            cnt++;
            u1=min(u1, i);                                                                     //满足字典序
        }
        else if(deg[i]!=0) u2=min(u2, i);
    if(cnt!=0&&cnt!=2){ cout<<"No Solution"<<endl; return 0; }             //奇点数不满足(2)
    if(cnt==0) dfs(u2);
    else dfs(u1);
    reverse(ans.begin(), ans.end());                                                             //反转回/链路
    if(ans.size()>n+1){ cout<<"No Solution"<<endl; return 0; }                //代表不连通图情况(1)
    for(int i=0;i<ans.size();i++)
        cout<<tochar(ans[i]);
    cout<<endl;
    return 0;
}

 

洛谷1341 无续字母对

标签:==   ret   个数   div   out   pre   情况   clu   区分大小写   

原文地址:http://www.cnblogs.com/beiju-z/p/7725414.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!