2103: 士兵排队问题
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 37 Solved: 11
[ Submit][ Status][ Web Board]
Description
有N个士兵(1≤N≤26),编号依次为 A,B,C,…,队列训练时,指挥官要把一些士兵从高到矮一次排成一行,但现在指挥官不能直接获得每个人的身高信息,只能获得“P1比P2高”这样的比较 结果(P1、P2∈A,B,C,…,Z,记为 P1>P2),如”A>B”表示A比B高。
请编一程序,根据所得到的比较结果求出一种字典序最小的排队方案。
(注:比较结果中没有涉及的士兵不参加排队)
Input
比较结果从文本文件中读入(文件由键盘输入),每个比较结果在文本文件中占一行。
Output
若输入数据无解,打印“No Answer!”信息,否则从高到矮一次输出每一个士兵的编号,中间无分割符,并把结果写入文本文件中,文件由键盘输入:
Sample Input
A>B
B>D
F>D
Sample Output
ABFD
HINT
Source
2153: D.ly的排队问题
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 45 Solved: 19
[ Submit][ Status][ Web Board]
Description
马上要上体育课了,上体育课之前总归是要排个队的,ly作为班长,怎么排队的问题只能由她来解决,但是马上要上课了,ly又不清楚所有人的身高,她又不好意思问每个人的身高,因为这样会显的自己很不负责,于是她只能通过肉眼观察...那么问题来了,她只能观察出两个人A和B谁高谁矮,但是她没有办法排出一个序列。
ly都已经帮你出了两次主意赢过wjw,那么现在她需要你的帮助,你可以帮她吗?
(ly会告诉你A和B谁高,如果A比B高,会用A>B来表示)
Input
只有一组数据,每个比较结果占一行,读取到文件结束
Output
若输入数据无解,则输出"No Answer!",否则从高到低输出每个人的名字,中间没有分割符
若有多种情况,输出字典序最小的答案
Sample Input
E>A
A>S
S>Y
Sample Output
EASY
HINT
Source
【解析】
为什么两题只写一个解析?因为两题一模一样的,传说中的“真·换汤不换药”。写了一个代码没改直接往另一个ctrl+c就能过
解析挺详细的,不过得先自学一下:用vector建立邻接表,拓扑排序的思想,优先队列是什么。其它,应该没了。
【代码】:
#include <bits/stdc++.h>
using namespace std;
vector<int> mp[52];
priority_queue< int, vector<int>, greater<int> > q;//因为字典序,所以用小顶堆
int ans[52], num[52], vis[52];
int main()
{
char s[5];
while (~scanf(" %s", s))
{
int i = s[0] - 'A', j = s[2] - 'A';
vis[i] = vis[j] = 1;//只记录i,j点的存在
mp[i].push_back(j);
num[j]++;//j点入度+1
}
for (int i = 0; i < 26; i++)//将入度为0的点推入优先队列
if (!num[i]&&vis[i])
q.push(i);
int count = 0;//记录答案个数
while (!q.empty())
{
int tmp = q.top();//取出入度为0的点
q.pop();
ans[count++] = tmp;//保存答案
int k = mp[tmp].size();
for (int i = 0; i < k; i++)//对改点
{
int id = mp[tmp][i];
if (!(--num[id]))
q.push(id);
}
}
for (int i = 0; i < 26; i++)//检查是否还存在入度不为0的点,即不存在任何一个连通子图
if (num[i] > 0)
{
printf("No Answer!\n");
return 0;
}
for (int i = 0; i < count; i++)//输出答案就好了,但是这两题答案不需要换行!!!!!
printf("%c", ans[i] + 'A');
}