集训考试题(CF510C Fox And Names的简化版)

摘要:
题目描述给定n个由小写字母组成的字符串,请你求出一个字母表顺序,使得这n个字符串是按照字典序升序排列的,数据保证存在合法的字母表顺序。输入格式第一行一个整数n.接下来n行,每行一个字符串。输出格式一行,一个a到z各出现一次的字符串,表示字母表顺序。lin[s[i][j]-'a'][s[i+1][j]-'a']){//建立top关系//建图58lin[s[i][j]-'a'][s[i+1][j]-'a']=1;59in[s[i+1][j]-'a']++;60}61}62elseifflag=0;63}64if(!

题目描述
给定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个,显然是不合法的

1 #include<bits/stdc++.h>
2 using namespacestd;
3 const int maxn = 1100;
4 int n, top = 0;
5 chars[maxn][maxn], ans[maxn];
6 int in[maxn], lin[maxn][maxn];//lin表示两个字符串连接一条边bulabulabula 
7 bool flag = 1;
8 
9 inline intread() {
10     int x = 0, y = 1;
11     char ch =getchar();
12     while(!isdigit(ch)) {
13         if(ch == '-') y = -1;
14         ch =getchar();
15 }
16     while(isdigit(ch)) {
17         x = (x << 1) + (x << 3) + ch - '0';
18         ch =getchar();
19 }
20     return x *y;
21 }
22 
23 queue<int>q;
24 inline booltopsort_solve() {
25     for(int i = 0; i < 26; ++i)
26         if(!in[i]) {
27 q.push(i);
28             ans[++top] = char(i + 'a');
29 }
30     while(!q.empty()) {
31         int k =q.front(); q.pop();
32         for(int i = 0; i < 26; ++i)
33             if(lin[k][i]) {
34                 in[i]--;
35                 if(!in[i]) {
36                     ans[++top] =char(i + 'a');
37 q.push(i);
38 }
39 }
40 }
41     if(top < 26) return 0;
42     else return 1;
43 }
44 
45 intmain() {
46     memset(in, 0, sizeof(in));
47     memset(lin, 0, sizeof(lin));
48     n =read();
49     for(int i = 0; i < n; ++i)
50         cin >>s[i];
51     for(int i = 0; i < n - 1; ++i) {
52         int len1 =strlen(s[i]);
53         int len2 = strlen(s[i + 1]);
54         int j = 0;
55         while(j < len1 && j < len2 && s[i][j] == s[i + 1][j]) j++;
56         if(j < len1 && j <len2) {
57             if(!lin[s[i][j] - 'a'][s[i + 1][j] - 'a']) {//建立top关系//建图 
58                 lin[s[i][j] - 'a'][s[i + 1][j] - 'a'] = 1;
59                 in[s[i + 1][j] - 'a']++;
60 }
61 }
62         else if(len1 > len2) flag = 0;
63 }
64     if(!flag) cout << "Impossible" << '';
65     else if(flag) {
66         flag =topsort_solve();
67         if(!flag) cout << "Impossible" << '';
68         else{
69             for(int i = 1; i <= top; ++i)
70                 cout <<ans[i];
71             cout << '';
72 }
73 }
74     return 0;
75 }

免责声明:文章转载自《集训考试题(CF510C Fox And Names的简化版)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇更换Sublime Text主题字体IE浏览器的ActiveXObject对象以及FileSystemobject的应用扩展(完成)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Python--画图时希腊字母的显示

主要介绍采用Matplotlib模块画图时,横纵坐标或者标题如果要书写希腊字母,该如何处理这一问题。 1. Matplotlib中支持LaTex语法,输入格式为:r'$Delta$' #其中的Delta对应于希腊字母的Δ r'$Delta$rv' #对应于Δrv 2. LaTex语法中希腊字母表: 希腊字母小写、大写 LaTeX形式 ,信息来源:https...

Unicode字符列表(超完整)

Unicode字符列表(超完整)Unicode, 字符, 列表代码 显示 描述U+0020  空格 U+0021 ! 叹号 U+0022 " 双引号 U+0023 # 井号 U+0024 $ 价钱/货币符号 U+0025 % 百分比符号 U+0026 & 英文“and”的简写符号 U+0027 ' 引号 U+0028 ( 开 圆括号 U+0029...

windows下mysql数据库表名大小写不敏感

  最近新入职,领导让做个小功能先练练手。是一个添加分类的功能,有添加和列表,很简单。功能做完后提交,结果在线上出现一个大大的500。   但是我再本地环境下是正常的,我以为可能是php的版本不一致导致的问题,就仔细看代码,看看有没有什么不合理的地方,然后在提交,还是500。然后又看,又提,依然是500。很不解啊,只有问领导了,领导说,是线上mysql字段...