• 蓝桥杯 士兵排队问题 拓扑排序


    题目描述
      有N个士兵(1≤N≤26),编号依次为A,B,C,…,队列训练时,指挥官要把一些士兵从高到矮一次排成一行,但现在指挥官不能直接获得每个人的身高信息,只能获得“P1比P2高”这样的比较结果(P1、P2∈A,B,C,…,Z,记为 P1>P2),如”A>B”表示A比B高。
      请编一程序,根据所得到的比较结果求出一种符合条件的排队方案。
      (注:比较结果中没有涉及的士兵不参加排队)
    输入要求
      比较结果从文本文件中读入(文件由键盘输入),每个比较结果在文本文件中占一行。
    输出要求
      若输入数据无解,打印“No Answer!”信息,否则从高到矮一次输出每一个士兵的编号,中间无分割符,并把结果写入文本文件中,文件由键盘输入:
    样例输入
    A>B
    B>D
    F>D
    样例输出
    AFBD
    图论的拓扑排序。
    待学习。
    大佬的思路:
    裸的拓扑排序,简单描述一下: 记录每个节点的入度,每次从栈中挑选一个入度为0的点并把其下级节点的入度-1,酱如果下级节点入度将为0,随即将其入栈(有些点可能会一直被压在栈底,没关系,因为没有先后关系的节点顺序是无所谓的),重复此操作,直至栈空.  如果此时还存在入度大于0的节点,则无解(这个可以通过记录出栈的节点个数判断).
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<queue>
     5 #include<stack>
     6 #include<cstring>
     7 #include<string>
     8 #include<vector>
     9 #include<cmath> 
    10 #include<map>
    11 #define mem(a,b) memset(a,b,sizeof(a))
    12 #define mod 1000000007
    13 using namespace std;
    14 typedef long long ll;
    15 const int maxn = 1e5+5;
    16 const double esp = 1e-7;
    17 const int ff = 0x3f3f3f3f;
    18 map<int,int>::iterator it;
    19 
    20 vector<int> mp[52];
    21 stack<int> q;
    22 int ans[52],num[52],vis[52];
    23 
    24 int main()
    25 {
    26     char in[5];
    27     while(scanf(" %s",in) !=EOF)
    28     {
    29         int i = in[0]-'A',j = in[2]-'A';
    30         vis[i] = vis[j] = 1;
    31         mp[i].push_back(j);
    32         num[j]++;
    33     }        
    34     
    35     int cnt = 0;
    36     for(int i = 0;i< 26;i++)
    37     {
    38         if(!num[i]&&vis[i])
    39             q.push(i);
    40     }
    41     
    42     while(!q.empty())
    43     {
    44         int tmp = q.top();
    45         q.pop();
    46         ans[++cnt] = tmp;
    47         
    48         int k = mp[tmp].size();
    49         
    50         for(int i = 0;i< k;i++)
    51         {
    52             int id = mp[tmp][i];
    53             if(!(--num[id]))
    54                 q.push(id);
    55         }    
    56     }
    57     
    58     for(int i = 0;i< 26;i++)
    59         if(num[i]> 0)
    60         {
    61             cout<<"No Answer!"<<endl;
    62             return 0;
    63         }
    64     
    65     for(int i = 1;i<= cnt;i++)
    66         printf("%c",ans[i]+'A');
    67     
    68     return 0;
    69 }
  • 相关阅读:
    Java 8 并行流与串行流
    Java 8 新增的 Stream
    Java 8 新增的 Lambda 表达式
    《CSS揭秘》 |用户体验与结构布局
    《CSS揭秘》 |阴影
    《CSS揭秘》 |形状
    《CSS揭秘》 |前言
    《CSS揭秘》 |背景与边框
    《CSS揭秘》 |CSS编码技巧
    《CSS揭秘》 |检测属性与属性值
  • 原文地址:https://www.cnblogs.com/fx1998/p/12742573.html
Copyright © 2020-2023  润新知