烦人的幻灯片——拓扑排序

烦人的幻灯片

  • 烦人的幻灯片
    • 问题描述
    • 输入输出格式
      • 输入格式
      • 输出格式
    • 输入输出样例
      • 输入样例:
        • 输入样例一:
        • 输入样例二:
      • 输出样例:
        • 输出样例一:
        • 输出样例二:
  • 正确做法
    • 拓扑排序
  • 代码

烦人的幻灯片——拓扑排序_第1张图片

烦人的幻灯片

问题描述

李教授于今天下午做一个非常重要的演讲。不幸的是他不是一个非常爱整洁的人,他把自己做演讲要用的幻灯片随便堆放在一起。因此,演讲之前他不得不去整理这些幻灯片。做为一个讲求效率的学者,他希望尽可能简单地完成它。情况是这样,教授这次演讲一共要用n张幻灯片(n≤26),这n张幻灯片按照演讲要使用的顺序已经用数字1,2,…,n在上面编上了号。因为幻灯片是透明的,所以我们不能一下子看清每一个数字所对应的幻灯片。

现在我们用大写字母A,B,C,。。。再次把幻灯片依次编上号,如图如示,我们可以很快发现编号为A的幻灯片是第4张,把它抽出来后我们又可以确定编号为C的幻灯片是第2张,。。。

你的任务是编写一个程序,把幻灯片的数字编号和字母编号对应起来,显然这种对应应该是唯一的;若是出现多种对应的情况或是某些数字编号和字母对应不起来,我们就称对应是无法实现的。

输入输出格式

输入格式

文件第一行只有一个数n,表示有n张幻灯片,接下来的n行第行包括4个整数Xmin,Xmax,Ymin,Ymax(整数之间用空格分开),为幻灯片的坐标,这n张幻灯片按其在输入文件中出现的顺序从前到后依次编号为A,B,C,。。。再接下来的n行依次为n个数字编号的坐标X,Y,显然在幻灯片之外是不会有数字的。

输出格式

若是对应可以实现,你的输出文件应该包括n行,每一行为一个字母和一个数字,并且各行以字母的升序排列,注意输出的字母要大写并且顶格;反之,若是对应无法实现,在文件的第一行顶格输出None即可。行首行末无多余空格。

输入输出样例

输入样例:

输入样例一:

4
6 22 10 20
4 18 6 16
8 20 2 18
10 24 4 8
9 15
19 17
11 7
21 11

输入样例二:

2
0 2 0 2
0 2 0  2
1 1
1 1

输出样例:

输出样例一:

A4
B1
C2
D3

输出样例二:

None

正确做法

拓扑排序

拓扑排序是一种对有向无环图(DAG)进行排序的算法。在拓扑排序中,图中的节点表示任务或事件,有向边表示任务之间的依赖关系。拓扑排序的目标是找到一种排序方式,使得所有任务都按照依赖关系的顺序被执行。

拓扑排序的步骤如下:

  1. 初始化一个队列,将所有入度为0的节点加入队列中。
  2. 从队列中取出一个节点,并将其输出。
  3. 将该节点的所有邻接节点的入度减1。
  4. 如果某个邻接节点的入度变为0,将其加入队列中。
  5. 重复步骤2-4,直到队列为空。
  6. 拓扑排序的过程可以理解为不断移除入度为0的节点,并将其输出。如果图中存在环路,则无法进行拓扑排序,因为环路中的节点无法确定顺序。

拓扑排序的应用非常广泛,例如任务调度、编译顺序、依赖关系分析等。它可以帮助我们理清任务之间的依赖关系,确保任务按照正确的顺序执行,避免出现循环依赖或执行顺序混乱的情况。

代码

#include
using namespace std;
struct pian{ int x1,x2,y1,y2; }p[30];
struct dian{ int x,y,b; }d[30];
int n,l,z[30];
bool tu[30][30],o[30];
bool t(int x,int y,int x1,int x2,int y1,int y2)
{
	return x>=x1&&x<=x2&&y>=y1&&y<=y2;
}
int main()
{
    cin >>n;
    for (int i=1;i<=n;i++)
		cin >>p[i].x1 >>p[i].x2 >>p[i].y1 >>p[i].y2;
	for (int i=1;i<=n;i++)
	{
		cin >>d[i].x >>d[i].y;
		for (int j=1;j<=n;j++)
			if (t(d[i].x,d[i].y,p[j].x1,p[j].x2,p[j].y1,p[j].y2))
			{
				d[i].b++;
				tu[j][i]=1;
			}
	}
	for (int k=1;k<=n;k++)
		for (int tmp=0,i=1;i<=n;i++)
			if (!o[i] && d[i].b==1)
			{
				for (int j=1;j<=n;j++)
					if (tu[j][i])
					{
						tmp=j;
						break;
					}
				z[tmp]=i;
				for (int j=1;j<=n;j++)
					if (tu[tmp][j])
					{
						tu[tmp][j]=0;
						d[j].b--;
					}
				l++;
				break;
			}
	if (l!=n)
	{
		cout <<"None";
		return 0;
	}
	for (int i=1;i<=n;i++)
		cout <<char(64+i) <<z[i] <<endl;
    return 0;
}

你可能感兴趣的:(C++专栏,算法,开发语言,c++)