H106OJ排序算法士兵排序问题

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]);
		}

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值