蓝桥杯2025年第十六届省赛真题-冷热数据队列(C语言)

题目描述

小蓝是一名计算机专业的学生,最近他学习了《操作系统》、《数据结构》 等课程,他设计了一种名为 “冷热数据队列” 的数据结构,来对数据页进行管理。 

冷热数据队列 q 可以看做由两个子队列组成:长度为 n1 的热数据队列 q1 和长度为 n2 的冷数据队列 q2 。当我们需要访问某个数据页 p 时:

1)若 p 不在队列 q 中(即既不在 q1 中,也不在 q2 中),则加载数据页 p ,并插入到 q2 的首部。 

2)若 p 已经在队列 q 中,则将 p 移动至 q1 首部。 

3)当 q1 或 q2 队列容量不足时,会将其尾部的数据页淘汰出去。 

4)当 q1 已满,但 q2 未满时,从 q1 中淘汰出的数据页会移动到 q2 首部。

输入格式

输入的第一行包含两个正整数 n1, n2 ,用一个空格分隔。 

第二行包含一个整数 m ,表示操作次数。 

第三行包含 m 个正整数 v1, v2, · · · , vm ,表示依次访问到的数据页的编号, 相邻整数之间使用一个空格分隔。

输出格式

输出两行。 

第一行包含若干个整数,相邻整数之间使用一个空格分隔,依次表示 q1 中 的数据页。 

第二行包含若干个整数,相邻整数之间使用一个空格分隔,依次表示 q2 中 的数据页。

样例输入

3 3
10
1 2 3 4 3 2 2 1 3 4

样例输出

4 3 2
1

提示

【样例说明】

                                                       

屏幕截图 2025-04-16 104717.png

【评测用例规模与约定】 

对于 20% 的评测用例,1 ≤ n1, n2 ≤ 10 ,1 ≤ m ≤ 10 ; 

对于 40% 的评测用例,1 ≤ n1, n2 ≤ 20 ,1 ≤ m ≤ 100 ; 

对于 60% 的评测用例,1 ≤ n1, n2 ≤ 100 ,1 ≤ m ≤ 1000 ; 

对于 80% 的评测用例,1 ≤ n1, n2 ≤ 103 , 1 ≤ m ≤ 104 ; 

对于所有评测用例,1 ≤ n1, n2 ≤ 104 ,1 ≤ m ≤ 105 ,0 ≤ vi ≤ 104 。

思路

入队出队这种可以用结构体来做,设两个结构体,代表两个队列,根据情况设置入队出队的操作

有新数据首先在两队列中查找,都不在的话就加入第二队,并删除多余元素;在第一队就进行队内调整,可以先删去对应元素,再在首位添加;在第二队就将对应元素移动到第一队,并将多出的元素移动到第二队,因为第二队的元素移动,所以一定处于不满状态

结构体很久没用了,很生疏,又因为结构体末尾的指针我不会用,所以就没设,而是用一个函数查找末尾元素


#include<stdio.h>
#include<stdlib.h>

typedef int ElemType;
typedef struct QNode {
	ElemType data;
	struct QNode* next;
}QNode;
typedef struct Queue {
	struct QNode* front;
	ElemType length;
}Queue;

void InitQueue(Queue* Q, int n){
	Q->front = NULL;
	Q->length = n;//记录队列最大长度
}

int inQueue(int v, Queue* Q) {//检测数据在其中,如果有数据就同时删除
	if (Q->front == NULL)
		return 0;
	QNode* q = Q->front;
	if (q->data == v) {
		Q->front = q->next;
		return 1;
	}
		
	QNode* q2 = q->next;
	while (q2) {
		if (q2->data == v) {//同时删除数据,便于之后添加
			q->next = q2->next;
			free(q2);
			return 1;
		}
			
		q = q->next;
		q2 = q2->next;
	}
	return 0;
}
int QueueLen(Queue* Q) {//当前数据长度
	int length = 0;
	if (Q->front == NULL)
		return 0;
	QNode *q;
	q = Q->front;
	while (q) {
		length++;
		q = q->next;
	}
	return length;
}

void joinQueue(Queue* Q, int v) {//加入首位元素
	struct QNode* q = (struct QNode*)malloc(sizeof(struct QNode));
	q->data = v;
	q->next = Q->front;
	Q->front = q;
}
void deleteQueue(Queue* Q) {//删除末尾元素
	QNode *q1,*q2;
	q1 = Q->front;
	if (!q1->next) {
		Q->front = NULL;
		free(q1);
		return;
	}
	q2 = q1->next;
	while (q2&&q2->next) {
		q1 = q1->next;
		q2 = q2->next;
	}
	q1->next = NULL;
	free(q2);
}
void deletedQueueMid(Queue* Q, int v) {//删除其中元素
	QNode *q1,*q2;
	q1 = Q->front;
	if (q1->data == v) {
		Q->front = q1->next;
		free(q1);
		return;
	}
	q2 = q1->next;
	while (q2) {
		if (q2->data == v) {
			q1->next = q2->next;
			free(q2);
			return;
		}
			
		q1 = q1->next;
		q2 = q2->next;
	}

}
int findLost(Queue* Q) {//查找末尾元素
	QNode* q1=Q->front;
	int k = 0;
	while (q1) {
		k = q1->data;
		q1 = q1->next;
	}

	return k;

}
int main() {
	int n1, n2;
	long long m;
	int i,v;
	struct Queue* q1 = (struct Queue*)malloc(sizeof(struct Queue));
	struct Queue* q2 = (struct Queue*)malloc(sizeof(struct Queue));
	scanf("%d %d", &n1, &n2);
	InitQueue(q1, n1);
	InitQueue(q2, n2);
	scanf("%lld", &m);
	for (i = 0;i < m;i++) {
		scanf("%d", &v);
		int inQ1 = inQueue(v, q1);
		int inQ2 = inQueue(v, q2);
		if (!inQ1 && !inQ2) {//不在两表内
			joinQueue(q2, v);
			if (QueueLen(q2) > n2) {//数量过多,删除
				deleteQueue(q2);
			}
		}
		else if (inQ1) {//在第一层中
			joinQueue(q1, v);
		}
		else {//在第二层中
			joinQueue(q1, v);
			if (QueueLen(q1) > n1) {//超出空间
				int k = findLost(q1);//末尾元素
				deleteQueue(q1);
				joinQueue(q2, k);
			}
		}
	}
	QNode *q = q1->front;
	while (q) {
		printf("%d ", q->data);
		q = q->next;
	}
	printf("\n");

	q = q2->front;
	while (q) {
		printf("%d ", q->data);
		q = q->next;
	}
	printf("\n");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值