BUAA(2021春)空闲空间合并(期末考试模拟题)——结构体二级排序

48 篇文章 152 订阅

看前须知

要点介绍和简要声明.

考试回顾

格式控制输入输出——期中考试模拟题(简单的分类讨论).

标识符的识别(期中考试题)——题目说的不清不楚但其实不难.

空闲空间申请模拟(期中考试题)——注意读题,难度其实一般.

网络打印机选择(北京学院数据结构18级期末压轴题)——伪树状数组(这题杀我)(ಥ_ಥ).

查家谱(士谔书院16级期末)——找最近公共祖先.

图的直径(士谔书院15级期末)——求有向图的最大路径:Floyd的妙用.

快逃离卷怪统治的BUAA——求树中的最短路径+中序和后序恢复二叉树.

网络打印机延迟率计算(士谔18级期末改编)——伪树状数组+树的直径.

题目内容

问题描述

一个内存空间块可用一对起始地址和结束地址表示,如[0,100]。对于两个内存空间块:[0,100]和[101,200],这两个空间是相邻的,所以可以合并成一个空间块:[0,200]。编写程序,输入一组空闲内存空间,对相邻空间进行合并,然后按照空间块的起始地址由小到大输出。注意:内存空间块不会存在重叠的情况
算法之一提示:可先将输入的空间块按起始地址排序,然后进行合并。

输入形式

从控制台输入内存空间块的个数(大于等于1,小于等于100),然后分行输入每个内存空间块的起始地址和结束地址(地址用大于等于0,并且小于等于100000的整数表示),两地址间以一个空格分隔

输出形式

将合并后的内存空间块按照空间块的起始地址由小到大输出**,每个空间块独占一行**,先输出起始地址,再输出结束地址,两地址间以一个空格分隔。

样例

样例输入:

10

48 99

0 39

1024 2047

100 479

4000 5999

600 799

40 47

2048 3047

840 859

8000 8999

样例输出:

0 479

600 799

840 859

1024 3047

4000 5999

8000 8999

样例说明

输入了10个内存空间块,其中:[0,39]、[40,47]、[48,99]和[100,479]相邻,可以合并成一个空间块:[0,479];[1024,2047]和[2048,3047]相邻,可以合并成[1024,3047]。合并后还有6个内存空间块,按照空间块的起始地址由小到大输出。

题解

思考和详解

和连续线段那道题一模一样,只要会结构体二级排序,这道题真的有手就行。对于已经合并的区块,我们可以把起点设置为-1(题目要求起点一定大于等于0),输出的时候就可以巧妙的避免输出它们了。

参考代码

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
#include<stdbool.h>
int i,j; 
struct node{
	int a;	//起点 
	int b;	//终点 
}s[20000];
int compare(const void*p1,const void*p2)
{
	struct node *x=(struct node*)p1;
	struct node *y=(struct node*)p2;
	if(x->a!=y->b)return x->a-y->a;	//先排起点 
	else return x->b-y->b;			//再排终点 
}
int main()
{	
	int n;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%d %d",&s[i].a,&s[i].b);	//输入 
	}
	qsort(s,n,sizeof(struct node),compare);	//排序 
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			if(s[i].b+1==s[j].a)	//满足合并条件 
			{
				s[i].b=s[j].b;
				s[j].a=-1;	//巧妙设为-1(题目说起点一定大于等于0) 
			}
		}
	}
	qsort(s,n,sizeof(struct node),compare);	//再排 
	for(i=0;i<n;i++)
		if(s[i].a!=-1)	//如果不是已经合并的 
		printf("%d %d\n",s[i].a,s[i].b);	//输出 
	return 0;
}
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值