CodeForces - 510C Fox And Names
CodeForces - 510C Fox And Names
题解:建图+拓扑排序
首先题目想让你按照给定的字符串修改字母表的字母序,我们很容易想到拓扑排序,但是这怎么建图?实际上对于两个输入的字符串,s1,s2,s1在s2的上面,如果他们某个位置的字符不相同,那么我们需要建一条从s1[i]-->s2[i]的边,当然题目中只有26个点,因为是小写字母,这样就实现了建边;我们再来考虑什么样的情况会出现不可能,首先是图上有环,其次如果s1字符串在s2的上面,但是lens1>lens2,并且他们相同长度的字符一模一样这样肯定不能实现字母序,
例如s1:aaaaa
s2:aaaa
#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define all(x) (x).begin(), (x).end()
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 2e5 + 10;
int n;
string s[110];
vector<int> g[30];
int du[30];
queue<int> q;
vector<int> ans;
int main(void)
{
Zeoy;
int t = 1;
// cin >> t;
while (t--)
{
cin >> n;
for (int i = 1; i <= n; ++i)
cin >> s[i];
int flag = 1;
for (int i = 1; i <= n - 1; ++i)
{
int ischange = 0;
int len1 = s[i].length();
int len2 = s[i + 1].length();
for (int j = 0; j < min(len1, len2); ++j)
{
if (s[i][j] != s[i + 1][j])
{
ischange = 1;
g[s[i][j] - 'a' + 1].push_back(s[i + 1][j] - 'a' + 1);
du[s[i + 1][j] - 'a' + 1]++;
break;
}
}
if (!ischange && len1 > len2)
{
cout << "Impossible\n";
return 0;
}
}
for (int i = 1; i <= 26; ++i)
{
if (du[i] == 0)
q.push(i);
}
int num = 0;
while (q.size())
{
int t = q.front();
ans.push_back(t);
num++;
q.pop();
for (auto i : g[t])
{
du[i]--;
if (du[i] == 0)
q.push(i);
}
}
if (num < 26)
cout << "Impossible\n";
else
{
for (auto i : ans)
{
cout << (char)(i + 'a' - 1);
}
cout << endl;
}
}
return 0;
}