首页 技术 正文
技术 2022年11月12日
0 收藏 707 点赞 4,156 浏览 2013 个字

题目描述
给定n个由小写字母组成的字符串,请你求出一个字母表顺序,使得这n个字符串是按照字典序升序排列的,数据保证存在合法的字母表顺序。
如果存在多个解,输出字典序最小的那个。

输入格式
第一行一个整数n.接下来n行,每行一个字符串。
输出格式
一行,一个a到z各出现一次的字符串,表示字母表顺序 。

样例读入:
10
petr
egor
endagorion
feferivan
ilovetanyaromanova
kostka
dmitriyh
maratsnowbear
bredorjaguarturnik
cgyforever
样例输出:
aghjlnopefikdmbcqrstuvwxyz

先水一下在考场上的骗分思路:
可以发现的是,非常有意思的,把所有的字符串的首字母提取出来,以样例为例,也就是:
peefikdmbc
去重后就是:
pefikdmbc
然后发现它在样例输出里存在,接着又发现,把其他的,没有在这个小串里出现的字幕按照正常的字母表顺序接在这个小串两边,就凑出了样例,
前半段自然是好凑,而后半段,我们则直接输出这个小串的首字母,也就是p,在字母表后没有出现的字母堆在后面,就凑出了样例:
前半段自然是:aghjlno
后半段自然是:qrstuvwxyz
然后我们就得到了样例输出:aghjlnopefikdmbcqrstuvwxyz
然后可能是存在某种正确性,但是一般不是字典序最小,但是我依旧骗到了大量的部分分

接着我们讲正解思路:
我们想要使得字符串的顺序有一个优先级,就意味着最基本的,他们的首字母有一个优先级
然后要是上下两个字符串的前半部分相等,那么就可以确定这之后的头一个字母的优先级
然后我们假设在一张图上优先级低的指向了优先级高的,也就是建立了一个拓扑序
我们根据拓扑序确定一个顺序。
优先级低的指向优先级高的,也就是将优先级高的的字母的入读加一
先将所有入度为0的存入答案数组,再按照拓扑序记录答案,最后输出即可
因为题目保证了一定合法,所以我们可以不考虑不合法的情况,但是如果一定有不合法的情况,我们判断也很简单
1.若两个字符串,一个字符串能够在另一个字符串中找到,且较长的字符串在短的字符串的上面,这是显然不合法的
2.若最后拓扑结束后,答案数组里存的字母不到26个,显然是不合法的

 #include<bits/stdc++.h>
using namespace std;
const int maxn = ;
int n, top = ;
char s[maxn][maxn], ans[maxn];
int in[maxn], lin[maxn][maxn];//lin表示两个字符串连接一条边bulabulabula
bool flag = ; inline int read() {
int x = , y = ;
char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') y = -;
ch = getchar();
}
while(isdigit(ch)) {
x = (x << ) + (x << ) + ch - '';
ch = getchar();
}
return x * y;
} queue<int> q;
inline bool topsort_solve() {
for(int i = ; i < ; ++i)
if(!in[i]) {
q.push(i);
ans[++top] = char(i + 'a');
}
while(!q.empty()) {
int k = q.front(); q.pop();
for(int i = ; i < ; ++i)
if(lin[k][i]) {
in[i]--;
if(!in[i]) {
ans[++top] =char(i + 'a');
q.push(i);
}
}
}
if(top < ) return ;
else return ;
} int main() {
memset(in, , sizeof(in));
memset(lin, , sizeof(lin));
n = read();
for(int i = ; i < n; ++i)
cin >> s[i];
for(int i = ; i < n - ; ++i) {
int len1 = strlen(s[i]);
int len2 = strlen(s[i + ]);
int j = ;
while(j < len1 && j < len2 && s[i][j] == s[i + ][j]) j++;
if(j < len1 && j < len2) {
if(!lin[s[i][j] - 'a'][s[i + ][j] - 'a']) {//建立top关系//建图
lin[s[i][j] - 'a'][s[i + ][j] - 'a'] = ;
in[s[i + ][j] - 'a']++;
}
}
else if(len1 > len2) flag = ;
}
if(!flag) cout << "Impossible" << '\n';
else if(flag) {
flag = topsort_solve();
if(!flag) cout << "Impossible" << '\n';
else {
for(int i = ; i <= top; ++i)
cout << ans[i];
cout << '\n';
}
}
return ;
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,488
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,903
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,737
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,489
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,128
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,290