div1的A题也是比较裸的拓扑排序题,但是英语确实有点难理解。
题目链接~~~
题意:给定一些字符串,然后前面出现的字符在后面出现字符的前面。
注意点:
1. 拓扑排序,我用的是优先队列,先输出,排在前面的字符。
2. 比较的是第一个不相同的字符。
3. 如果后面的字符串是前面字符串的子串,则不可能存在字典序。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 110;
int n, grath[maxn], to[maxn];
vector <int> G[maxn];
string now, pr;
void tosort()
{
priority_queue <int, vector<int>, greater<int> > pre;
// queue<int>pre;
for(int i = 1; i <= 26; i++) if(!grath[i]) pre.push(i);
int sum = 0;
while(!pre.empty())
{
int h = pre.top(); pre.pop();
to[++sum] = h;
// cout<<"sum = "<<sum<<endl;
for(int i = 0; i < G[h].size(); i++)
{
int a = G[h][i];
if(!(--grath[G[h][i]])) pre.push(G[h][i]);
}
}
// cout << "sum = "<<sum<<endl;
if(sum < 26)
printf("Impossible\n");
else
{
for(int i = 1; i <= sum; i++)
cout << char(to[i] - 1 + 'a');
printf("\n");
}
}
int main()
{
scanf("%d", &n);
{
pr = " ";
for(int i = 0; i <= 105; i++) G[i].clear(), grath[i] = 0;
for(int i = 0; i < n; i++)
{
cin >> now;
if(i == 0)
{
pr = now;
continue;
}
int len = min(now.size(), pr.size());
bool flag = false;
for(int i = 0; i < len; i++)
{
if(now[i] != pr[i])
{
flag = true;
G[pr[i] - 'a' + 1].push_back(now[i] - 'a' + 1);
grath[now[i] - 'a' + 1]++;
break;
}
}
if(!flag && now.size() < pr.size())
{
printf("Impossible\n");
return 0;
}
pr = now;
}
tosort();
}
return 0;
}