这题题意是根据被改变的字典序给出的字符串求出字典序。比较字典序大小就是看两个字符串第一个不同的字符或是在前面完全相同的情况下比较长度。所以当前面的条件都不满足时就是题目的impossible。这题主要就是找出相邻两个字符串中第一个不相等字符,由此我们就得出这两个字符串的字典序排列,在进行链式前向星存储和拓扑输出
点击查看代码
/* 台州第一深情 */
#include <bits/stdc++.h>
using namespace std;
using i64 = long;
using ll = long long;
typedef pair<int, int> PII;
const int N = 1e4 + 5;
string s[N];
struct Edge
{
int to, next;//next记录上一条边的位子
} edge[N];
int head[N], in[N], cnt;//head记录当前from连成的边的下标
void addedge(int from, int to)
{
edge[cnt] = {to, head[from]};
head[from] = cnt++;
in[to]++;
}
queue<int> p;
int tp()
{
priority_queue<int, vector<int>, greater<int>> q;//优不优先都可以,因为任意输出
for (int i = 0; i < 26; ++i)
{
if (!in[i])
q.push(i);
}
while (!q.empty())
{
int from = q.top();
q.pop();
p.push(from);
int i = head[from];
while (i != -1)
{
in[edge[i].to]--;
if (!in[edge[i].to])
{
q.push(edge[i].to);
}
i = edge[i].next;
}
}
return p.size() == 26;//因为要得出所有的排列,所以如果p的长度<26也是impossible也代表有环
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
memset(head, -1, sizeof(head));
cin >> s[0];
for (int i = 1; i < n; ++i)
{
cin >> s[i];
string s1 = s[i - 1], s2 = s[i];
int f = 0;
for (int j = 0; j < min(s1.size(), s2.size()); j++)
{
if (s1[j] != s2[j])
{
f++;
addedge(s1[j] - 'a', s2[j] - 'a');
break;
}
}
if (!f && s1.size() > s2.size())//如果前面的点都一样并且长度长的排在短的前面,那肯定是不行的
{
cout << "Impossible\n";
return 0;
}
}
if (tp())
{
while (p.size())
{
int i = p.front();
p.pop();
cout << char(i + 'a');
}
}
else
{
cout << "Impossible\n";
}
return 0;
}