ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

BIT计科大二小学期-程设-20.军训日记:查寝

2021-09-08 19:58:19  阅读:529  来源: 互联网

标签:输出 盒子 物体 next 查寝 100006 物品 20 BIT


一、题目

小军的军训进行到了一半了,今天军训教官搞了一波突然袭击,进行了一个寝的查。

提前了解到查寝消息的小军准备进行一波整理归纳,来使自己的寝室变得更加整洁。具体来说,小军有n件物品,放在n个盒子里,第i个盒子有物品i,小军会进行m次整理,第i次整理,小军会依次在第x个盒子顶拿走物品放入第y个盒子内,直至第x个盒子完全搬空。比如第1个盒子自顶向下有物品1、2,第2个盒子有物品3,将盒子1内的物品搬入盒子2内后结果是: 第1个盒子没有物品,第2个盒子自顶向下是2、1、3

现在,小军告诉你n还有m次操作具体是什么,你能告诉他最后每个盒子内有几个物品,他们具体是什么么?

输入:

一个正整数n代表盒子和物品数,一个正整数m代表整理归纳的次数

接下来m行输入,一行两个正整数x y,代表用上述的方法将盒子x的物品搬到盒子y里

1n≤10^5, 1≤m≤10^6, 1≤x,y≤n

题目保证x != y

输出;

有n行输出

第i行,先输出一个正整数k,表示第i个盒子内的物品数,接下来输出n个数,表示第i个盒子自顶向下的物品标号

注意:

行末无空格,文末有回车。


二、AC代码及注释

因为考虑顺序的话会用到链表,非常麻烦,所以我们不记盒内物体顺序,直接边输入、边操作、边存储每个盒子内最头和最尾两个物体的编号,存储n个物体中每个物体自己左邻右舍物体的编号(这两个邻居编号的顺序也是没有要求)。这样,输出的原理就从按盒内物体的前后顺序挨个输出,变为了先输出最头的物体,然后考察每个物体的左邻右舍是否被输出过,如果没有则输出。

不明白的话,举个例子。比如说,最后的结果是盒子1里有顺序为5,2,4,1,3,而计算机并不知道这个顺序,只知道盒子1里最头的是5,最尾的是3,以及每个物体相邻的左邻右舍。由于我们初始化存入左邻右舍next是所有元素都是0,所以一个物体 只有一个邻居时,可以是next[i][0]=0或者next[i][1]=0,而只有最头和最尾两个物体是这种情况。因此,从头开始,查找next[5]中除了0之外的另一个数,就是2,输出2并用flag数组标记。接着顺着查找next[2],看2的两个邻居,肯定一个是5一个是4,这时考察flag数组的标记,就可以知道5已经被输出过了,4还没有,所以2的下一个是4...以此类推

#include <stdio.h>
#include <stdlib.h>
 
int main()
{
	int m,n,t,flag[100006]={0}, next[100006][2]={0},head[100006]={0},end[100006]={0},num[100006]={0};
	scanf("%d %d",&n,&m);
	int i,j,x,y;
	for(i=1;i<=n;i++)//为了方便思考,n组数据我们选择从1到n而不是从0到n-1 
	{
		head[i]=i; end[i]=i; num[i]=1;//初始的时候是每个盒子里放着一个物品,是第几个盒子物品编号就是几 
	}
	for(i=0;i<m;i++)
	{
		scanf("%lld %lld",&x,&y);
		if(num[x]==0) continue;//每次输入的第一个盒子是空的的话,直接跳过了 
		else
		{
			if(num[y]==0)//如果第二个盒子是空的,直接倒着装进去就行了,很好理解
			{
				head[y]=end[x];
				end[y]=head[x];
			}
			else
			{
				if(next[head[x]][1]==0)      next[head[x]][1]=head[y]; //第一个盒子内的head物体只有一个邻居,所以看next中两个位置哪个空就把y的head物体放进去 
				else if(next[head[x]][0]==0) next[head[x]][0]=head[y];
				if(next[head[y]][1]==0)      next[head[y]][1]=head[x];//同理,给x的head配上邻居,也得对y进行同样的操作 
				else if(next[head[y]][0]==0) next[head[y]][0]=head[x];
				head[y]=end[x];// 第二个盒子新的head就是第一个盒子原来的end 
			}
			num[y]+=num[x];//别忘更新物体数量 
		    head[x]=0;//第一个盒子就空了 
		    end[x]=0;
		    num[x]=0;
		}
	}
	for(i=1;i<=n;i++)
	{
		if(num[i]==0) printf("0\n");
		else
		{
			printf("%d",num[i]);
			printf(" %d",head[i]);
			flag[head[i]]=1;//用flag数组存储数据是不是输出过了,输出过了设为1 
			t=head[i];
			for(j=1;j<num[i];j++)
			{
				if(next[t][0]!=0&&flag[next[t][0]]!=1) 
				{
					printf(" %d",next[t][0]);
					t=next[t][0];
					flag[t]=1;
				}
				if(next[t][1]!=0&&flag[next[t][1]]!=1)
				{
					printf(" %d",next[t][1]);
					t=next[t][1];
					flag[t]=1;
				}
			}
			printf("\n");
		}
	}
	return 0;
}

标签:输出,盒子,物体,next,查寝,100006,物品,20,BIT
来源: https://blog.csdn.net/m0_61229668/article/details/120186862

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有