您的位置:首页 > 其它

蓝桥杯—算法提高—士兵排队问题

2018-03-27 20:26 218 查看
试题  有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
思路:拓扑排序,需要注意没涉及的士兵不参加排队,所以建立一个标记数组记录参加排队的士兵,剩下的就是裸的拓扑排序。
代码:#include<bits/stdc++.h>

using namespace std;
const int maxn = 26;

vector<int> topo;
int vis[maxn], c[maxn];
int G[maxn][maxn];

bool dfs(int u)
{
c[u] = -1;//标记等于-1表示正在访问点u
for(int v = 0;v < maxn;v++)
{
if(G[u][v])
{
if(c[v] < 0)
/*当前递归正在访问v,而u也正在被访问,表示v可以到u,而现在u也可以到v
表示该有向图有环的存在,无拓扑排序*/ 
   return false;
else if(!c[v]&&!dfs(v))
   return false; 
}
}
c[u] = 1;//访问完毕
topo.push_back(u);
return true;
}

bool toposort()
{
memset(c, 0, sizeof(c));
for(int u = 0;u < maxn;u++)
{
if(!c[u])
   if(!dfs(u))
       return false;
}
return true;
}

void print()
{
if(!toposort())
{
printf("No Answer!\n");
return;
}
char tmp;
for(int i = topo.size()-1;i >= 0;i--)
{
if(vis[topo[i]])
{
tmp = topo[i] + 'A';
printf("%c", tmp);
}
}
printf("\n");
return;
}

int main()
{
char str[5];
memset(G, 0, sizeof(G));
memset(vis, 0, sizeof(vis));
while(cin >> str)
{
int u, v;
u = str[0] - 'A';
v = str[2] - 'A';
vis[u] = vis[v] = 1;
G[u][v] = 1;
}
print();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  拓扑排序