您的位置:首页 > 其它

洛谷1341 无序字母对

2015-10-24 15:29 387 查看
洛谷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在程序中的位置。

【代码】

#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;

const int maxn = 100;

int G[maxn][maxn];
int cnt[maxn];

int n,N=53;

int vis[maxn][maxn];
inline int calc(char c) {
if(c>='A'&&c<='Z') return (int)c-'A';
return (int)c-'a'+26;
}
inline char calc(int x) {
if(x>=0 && x<26) return (char)x+'A';
return (char)(x-26)+'a';
}

vector<int> ans;
void euler(int u) {
for(int v=0;v<N;v++) if(G[u][v]&&!vis[u][v]) {
vis[u][v]=vis[v][u]=1;
euler(v);
ans.push_back(v);              //如是入栈 逆向输出
}
}

int main() {
scanf("%d",&n);
char a,b;
for(int i=1;i<=n;i++) {
cin>>a>>b;
int x=calc(a),y=calc(b);
G[x][y]=G[y][x]=1;
cnt[x]++, cnt[y]++;
}
int tot=0,u1=1e8,u2=1e8;
for(int i=0;i<N;i++) {
if(cnt[i]&1) {
tot++;
u1=min(u1,i);
}
else if(cnt[i]) u2=min(u2,i);
}
if(tot!=0&&tot!=2) printf("No Solution\n");
else {
int u;
if(tot==0) u=u2; else u=u1;
euler(u);
ans.push_back(u);
for(int i=ans.size()-1;i>=0;i--) cout<<calc(ans[i]);
cout<<"\n";
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: