• Fox And Names CodeForces


    题意:新定义题,重新定义了字典序的概念( 即 a不一定小于b),已的n个单词是按 新字典序 从小到大排序的,求重新定义字典序的字母顺序。如果先后有矛盾输出  “Impossible”。

    思路:先把前缀一致的过滤,剩下将路径存入数组,并记录每个字母的入度;

    最后拓扑排序:若是不按照26原始字母顺序来,可以直接先将入度为0的全部放入队列并记录答案p[t++],再对队列里的字母开始出队且删除与之有关的边,若删除后,那个字母的入度为0,则可进入队列,答案p[t++],若入度不为0,则不操作。最后若答案长度小于26,说明有环,否则成功输出p数组。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<queue>
     4 #include<stack>
     5 #include <bitset>
     6 #include<set>
     7 #include<map>
     8 #include<unordered_map>
     9 #include<vector>
    10 #include<cmath>
    11 #include<string>
    12 #include<string.h>
    13 using namespace std;
    14 typedef long long ll;
    15 typedef pair<ll, int> pa;
    16 typedef unsigned long long ull;
    17 char s[105][105];
    18 int f[50], mapp[50][50], len[105];
    19 char p[1001];//存储拓扑排序结果;
    20 void tp() {
    21     int i, j, t = 0;
    22     queue<int>q;
    23     for (i = 0; i < 26; i++){//从小到大找出全部入度为0的字母
    24         if (!f[i]){
    25             q.push(i);
    26             p[t++] = i + 'a';
    27         }
    28     }
    29     while (!q.empty()){//进行拓扑排序
    30         int k = q.front();
    31         q.pop();
    32         for (i = 0; i < 26; i++){
    33             if (mapp[k][i] == 1){
    34                 f[i]--;
    35                 if (f[i] == 0){//直到入度为0才可以进去队列
    36                     q.push(i);
    37                     p[t++] = i + 'a';
    38                 }
    39             }
    40         }
    41     }
    42     if (t < 26){
    43         printf("Impossible
    ");
    44     }
    45     else{
    46         p[t] = '';
    47         printf("%s
    ", p);
    48     }
    49     return;
    50 }
    51 
    52 int main() {
    53     int n;
    54     cin >> n;
    55     for (int i = 0; i < n; i++) {
    56         cin >> s[i];
    57         len[i] = strlen(s[i]);
    58     }
    59     int flag = 0;
    60     for (int i = 0; i < n - 1; i++) {
    61         int len1 = len[i];
    62         int len2 = len[i + 1];
    63         int lenm = min(len1, len2);
    64         int k, a = 0;
    65         //最多比较到较短的单词结束
    66         for (k = 0; k < lenm; k++) {
    67             if (s[i][k] != s[i+1][k]) {
    68                 a = 1;
    69                 if (!mapp[s[i][k] - 'a'][s[i+1][k] - 'a']) {//没有出现过这两个字母的连接
    70                     mapp[s[i][k] - 'a'][s[i + 1][k] - 'a'] = 1;
    71                     f[s[i + 1][k] - 'a']++; //入度+1,相当于在它前面还有一个字母
    72                 }
    73                 break;
    74             }
    75         }
    76         if (!a) {//若是两个单词中某个是前缀必须是len1
    77             if (k != len1) {
    78                 flag = 1;
    79                 break;
    80             }
    81         }
    82         if (flag) {
    83             break;
    84         }
    85     }
    86     if (flag) {
    87         printf("Impossible
    ");
    88     }
    89     else {
    90         tp();
    91     }
    92     return 0;
    93 }

    若是按照26字母原始顺序,则遍历每次取出第一个入度为0的字母,依次删除与之有关的边,入度为负记录答案num[cns++],再取出第一个入读为0的边,直到在26次循环中某一次没有找到入度为0的边,说明有环。代码参考:https://blog.csdn.net/qq_41890797/article/details/81742221

     1 void tp()  //拓扑排序的核心代码
     2 {
     3     int p,flag,cns=0;
     4     for(int i=0; i<26; i++)
     5     {
     6         int flag=0;
     7         for(int j=0; j<26; j++)
     8         {
     9             if(!f[j])  //此时这个字母是最小的
    10             {
    11                 p=j;
    12                 flag=1;
    13                 break;
    14             }
    15         }
    16         if(!flag) //没有可确定的字母,矛盾了
    17         {
    18             printf("Impossible
    ");
    19             return;
    20         }
    21         f[p]--;
    22         num[cns++]=p+'a';
    23         for(int j=0; j<26; j++)
    24             if(map[p][j])
    25                 f[j]--;    //与p为前端的入度-1
    26     }
    27     num[cns]=0;//加 ‘/0’
    28     puts(num);
    29 }
  • 相关阅读:
    [ArcGIS API for JavaScript 4.8] Sample Code-Get Started-MapView,SceneView简介
    [C语言]易错知识点、小知识点复习(1)
    OpenID Connect Core 1.0(二)ID Token
    轻量ORM-SqlRepoEx 重大升级
    OpenID Connect Core 1.0(一)介绍
    轻量ORM-SqlRepoEx (五) 存储过程操作
    轻量ORM-SqlRepoEx (四)INSERT、UPDATE、DELETE 语句
    轻量ORM-SqlRepoEx (三)Select语句
    轻量ORM-SqlRepoEx (二)初始化SqlRepoEx
    轻量ORM-SqlRepoEx (一)SqlRepoEx介绍
  • 原文地址:https://www.cnblogs.com/0211ji/p/13443717.html
Copyright © 2020-2023  润新知