CF510C Fox And Names 题解
https://www.luogu.com.cn/problem/CF510C
思路
- 题意就是:确定一个小写字母的比较规则,使得给定的所有字符串在一开始就是按你确定的比较规则排序了的。
- 可以发现:对于前后一对字符串,找到第一对不同的字符,是要这两个字符有合法的大小关系,就能满足题意。
- 由于很显然:一个字母有多个字母在要比它小或者大。
- 所以:建图 —> 拓扑排序 —> 模拟。
如何判断 Impossible
- 分一下几种情况:
\(s_i\) | \(s_{i + 1}\) |
---|---|
hh | hh |
hh | hhb |
hhb | hh |
- 第一种情况题目的输入已经帮我们解决了:所有字符串两两不同。
- 剩下的分类特判即可。
Code
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <map>
using namespace std;
const int MAXN = 100 + 10;
int n;
int ans[MAXN], len_ans = 0;
int b[MAXN], top = 0;
int cen[MAXN], pre[50];
int s[MAXN][MAXN];
string SSS;
vector<int> c[50];
int main(){
cin >> n;
for(int i = 1; i <= n; i++){
cin >> SSS;
for(int j = 0; j < SSS.size(); j++){
s[i][j] = int(SSS[j] - 'a' + 1);
}
}
for(int i = 1; i < n; i++){
for(int j = 0; j < 100; j++){
if(s[i][j] == 0 || s[i + 1][j] == 0){
if(s[i][j] != 0 && s[i + 1][j] == 0){
cout << "Impossible";
return 0;
}
break;
}
if(s[i][j] != s[i + 1][j]){
c[s[i][j]].push_back(s[i + 1][j]);
pre[s[i + 1][j]]++;
break;
}
}
}
for(int i = 1; i <= 26; i++){
if(pre[i] == 0){
b[++top] = i;
}
}
while(top > 0){
int i = b[top];
top--;
for(int j : c[i]){
if(pre[j] > 0){
pre[j]--;
if(pre[j] == 0){
b[++top] = j;
}
}
}
ans[++len_ans] = i;
}
if(len_ans != 26){
cout << "Impossible";
return 0;
}
for(int i = 1; i <= len_ans; i++){
cout << char(ans[i] + 'a' - 1);
}
return 0;
}
标签:int,题解,Fox,++,CF510C,ans,MAXN,include
From: https://www.cnblogs.com/huangqixuan/p/18043179