当前位置: 代码迷 >> 综合 >> 【Codeforces Round #290 (Div. 2)-C. Fox And Names】 思维题+拓扑排序
  详细解决方案

【Codeforces Round #290 (Div. 2)-C. Fox And Names】 思维题+拓扑排序

热度:26   发布时间:2023-12-29 02:32:35.0

Codeforces Round #290 (Div. 2)-C. Fox And Names

题意

给你n个字符串,让你设计一种字典序使这n个字符串满足字典序从小到大给你n个字符串,让你设计一种字典序使这n个字符串满足字典序从小到大n使n
如果不能设计输出impossible如果不能设计输出impossibleimpossible
n&lt;=100;∣s∣&lt;=100n&lt;=100;|s|&lt;=100n<=100;s<=100

做法

n2扫描所有字符串,对使每两个串字典序不同的主要字母建图(也就是第一个不同的字母)n^2扫描所有字符串,对使每两个串字典序不同的主要字母建图(也就是第一个不同的字母)n2使
建图之后跑一下拓扑排序,如果满足拓扑序也就是没有环出现,那么直接输出拓扑序即可。建图之后跑一下拓扑排序,如果满足拓扑序也就是没有环出现,那么直接输出拓扑序即可。

坑点

判一下有没有一短一长前缀完全相同,但是长度不同字典序错误的情况。判一下有没有一短一长前缀完全相同,但是长度不同字典序错误的情况。
比如AAA,AA,但是AAA出现在前面,这种情况也应该输出impossible比如AAA,AA,但是AAA出现在前面,这种情况也应该输出impossibleAAAAAAAAimpossible

代码

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn = 105;
char str[maxn][maxn];
vector<int> v[maxn];
int ind[maxn], que[maxn],m;//ind数组要清空
bool topsort()//还要特判自环
{
    int qt = 0;for(int i = 0;i<26; ++i){
    if(ind[i] == 0) que[qt++] = i;}for(int i = 0; i < qt; ++i){
    int u = que[i];for(int j = 0; j < v[u].size(); ++j){
    if(--ind[v[u][j]] == 0) que[qt++] = v[u][j];}}return qt == 26;
}
int main()
{
    int n;int flag=0;//存储是否有前缀完全相同一长一短不满足字典序的情况scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%s",str[i]);for(int i=1;i<=n;i++){
    for(int j=i+1;j<=n;j++){
    int ff=0;int len1=strlen(str[i]);int len2=strlen(str[j]);for(int pos1=0,pos2=0;pos1<len1&&pos2<len2;pos1++,pos2++){
    if(str[i][pos1]!=str[j][pos2]){
    v[str[i][pos1]-'a'].push_back(str[j][pos2]-'a');ind[str[j][pos2]-'a']++;ff=1;break;}}if(ff==0&&len1>len2) flag=1;}}if(topsort()&&flag==0){
    for(int i=0;i<26;i++) printf("%c",(char)que[i]+'a');}else{
    printf("Impossible\n");}return 0;
}
  相关解决方案