Description:
有N个士兵(1≤N≤26),编号依次为A,B,C,…,队列训练时,指挥官要把一些士兵从高到矮一次排成一行,但现在指挥官不能直接获得每个人的身高信息,只能获得“P1比P2高”这样的比较结果(P1、P2∈A,B,C,…,Z,记为 P1>P2),如”A>B”表示A比B高。
请编一程序,根据所得到的比较结果求出一种符合条件的排队方案。
(注:比较结果中没有涉及的士兵不参加排队)
Input:
比较结果从文本文件中读入(文件由键盘输入),每个比较结果在文本文件中占一行。
Sample Input:
A>B
B>D
F>B
F<A
Output:
若输入数据无解,打印“No Answer!”信息,否则从高到矮一次输出每一个士兵的编号,中间无分割符,并把结果写入文本文件中,文件由键盘输入:
Sample Output:
AFBD
思路:
士兵排序这道题明显是一道拓扑排序问题,拓扑排序的解题思想是给每个节点都加上一个入度的数值,查找入度为0的节点,放入队列中,不断将队头出队,加入答案序列,并且减少与之连接点(即被指向点)的入度,直至队空。代码我用到了set用法还有队列,set作为一个容器是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序,set内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Red-Black Tree)。 (不知道c++Set用法的可以看这个:c++中set用法详解)
代码:
#include<iostream>
#include<queue>
#include<set>
using namespace std;
bool boolArray[26]; //bool类型数组初始化
set<int> arr[26]; //定义一个类型为int的set容器
set<int> ar[26];
int main()
{
char a, b, c;
while (cin>>a>>b>>c)
{
arr[a - 'A'].insert(c - 'A');
ar[c - 'A'].insert(a - 'A');
boolArray[a - 'A'] = true;
boolArray[c - 'A'] = true;
}
queue<int> qu;
for (int i = 0; i < 26; i++)
{
if (ar[i].size() == 0 && boolArray[i])
{
qu.push(i);
}
}
char p[26];
int m= 0;
while (!qu.empty())
{
int j = qu.front();
set<int>::iterator n; //定义一个名为n的迭代器
for (n= arr[j].begin(); n != arr[j].end(); n++)
{
int to = *n;
ar[to].erase(j);
if (ar[to].size()==0)
qu.push(to);
}
arr[j].clear();
p[++m] = (char)j + 'A';
qu.pop();
}
for (int i = 0; i < 26; i++)
{
if (ar[i].size() > 0)
{
puts("No Answer!");
return 0;
}
}
for (int i = 1; i <= m; i++)
{
printf("%c", p[i]);
}
}