原题链接
考察:拓扑排序
思路:
  不难,暴力建边+拓扑排序,impossible条件是出现环或者,比较长度时,长的排在短的前面.

Code

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 110,M = 30;
int n,h[M],idx,d[M],cnt[M];
string name[N];
struct Road{
	int fr,to,ne;
}road[N*N];
int cmp(string a,string b)
{
	int len = min(a.size(),b.size());
	for(int i=0;i<len;i++)
	  if(a[i]!=b[i]) return i;
	return len;
}
void add(int a,int b)
{
	road[idx].to = b,road[idx].ne = h[a],h[a] = idx++;
}
void topsort()
{
	queue<char> q;
	for(char i='a';i<='z';i++)
	  if(!d[i-'a']) q.push(i);
	string res;
	while(q.size())
	{
		char c = q.front();
		q.pop();
		int u = c-'a';
		cnt[u]++;
		if(cnt[u]>1) {puts("Impossible");return;} 
		res+=c;
		for(int i=h[u];~i;i=road[i].ne)
		{
			int v = road[i].to;
			if(--d[v]==0) q.push(v+'a');
		}
	}
	if(res.size()<26) puts("Impossible");
	else cout<<res<<endl;
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>name[i];
	memset(h,-1,sizeof h);
	bool ok = 1;
	for(int i=1;i<=n;i++)
	  for(int j=i+1;j<=n;j++)
	  {
	  	 if(!ok) break;
	  	 int x = cmp(name[i],name[j]);
	  	 int len = min(name[i].size(),name[j].size());
	  	 if(x==len&&name[i].size()>name[j].size()) ok = 0;
	  	 if(x==len) continue;
	  	 char c = name[i][x],b = name[j][x];
	  	 d[b-'a']++;
	  	 add(c-'a',b-'a');
	  }
	if(!ok) puts("Impossible");
	else topsort();
	return 0;
}