CSP练习10:公共钥匙盒

本文详细解析了一道复杂的CSP考试编程题,通过合理的数据结构设计和排序算法的应用,实现了钥匙借用和归还的逻辑处理,最终解决了问题并获得了满分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 本题的心路历程:

本题是大学期间第一次参加csp考试的第二题,当时因为编程是一个超级生手而且一个寒假都没有怎么碰编译器了,所以手很生。后来有几次动过再次参加csp的念头,所以就再次看到这个题,一直觉得很啰嗦而且是近几年来csp第二题中最复杂的一个(但是逻辑还是比较好,只是需要认真分析,代码长度有点长而已)

今天又重新整理了一下我的思路:

主要还是按照题目中描述的逻辑过程来完成,只是会用到很多数据结构,又融合了排序算法,使得我一直都不想去编这个题。

接下来介绍一下我的数据结构:

数组a[]用来存放盒子的每个钥匙钩上存放的钥匙,故起初的时候是按照顺序来的,可以在声明以后直接进行初始化。

b[]是一个bool类型的数组,是用来存放钩子上是否有一个钥匙,true表示有,false表示没有。

s[][3]是用来存放所有老师的使用情况,即系统的输入,在这里做了一个处理,就是把数组的第三个值没有直接存储为输入数据的使用时长,而是转换为使用完毕的时间。

r[]用来存放在同一个时刻有很多个教师要还钥匙的情况,因为按题中的要求,需要按照钥匙的编号从小到大进行还钥匙的过程,这里就需要包括一个sort的过程。

思路:

因为题目中需要最终显示钥匙全部归还后的情况,所以需要在最大的循环上确定循环的大小,所以引入了一个max变量。

按照时刻进行大循环处理,先还再借。还的时候先遍历知道有多少是还的,然后按照编号进行排序,然后进行还钥匙的处理,改变数组a和b,借的时候同样,进行遍历,只是不需要统计借的人数,按照数组r的顺序进行处理即可。这里用到一个search因为经过很多次的借还导致制定编号的钥匙不能直接知道它所在的钩子,导致不知道应该如何处理下标为几的数组a和b.

第一次代码:(40分)

在sort部分采用了qsort还引入了相关的头文件,但是发现在调用qsort的时候并没有成功因为第一次只有40分,经百度知道如不进行排序或者排序错误的话就很容易得40分,所以改变了进行排序的方式,采用了传统的冒泡排序的方式。

第二次代码:(100分)

#include <iostream>
#include <cstdlib>
using namespace std;

int search(int a[], int b, int n)
{
	for (int i = 0; i < n; i++) 
	{
		if (a[i] == b) 
		{
			return i;
		}
	}
}
int main(void) 
{
	int n;
	int k;
	cin >> n;
	cin >> k;
	int a[1000];
	bool b[1000];
	for (int u = 0; u < n; u++) 
	{
		a[u] = u + 1;
		b[u] = true;
	}//钥匙部分初始化,true表明钥匙放在钥匙盒里
	int s[10000][3];
	int r[10000];//用来处理多位老师同时还钥匙的情况
	int max = 0;//最晚结束时间
	//进行内容的输入
	for(int i = 0;i < k;i++)
	{
		cin >> s[i][0];
		cin >> s[i][1];
		cin >> s[i][2];
		s[i][2] = s[i][1] + s[i][2];
		if (s[i][2] > max) 
		{
			max = s[i][2];
		}
	}
	//cout << "max的值为" << max << endl;
	int count = 0;
	for (int t = 0; t <= max; t++) 
	{
		//每一个时刻都要处理,先还再取,还按钥匙的编号大小还
		count = 0;
		for(int m = 0;m < k;m++)
		{
			if (s[m][2] == t) //统计出所有在该时刻要还钥匙的人的钥匙号,因为要按照编号还
			{
				
				r[count] = s[m][0];
				count++;
			}
		}
		//排序
		/*if (count > 0) 
		{
			qsort(r, count - 1, sizeof(int), comp);
		}*/
		//cout << "打印r数组" << endl;
		//进行冒泡排序
		int temp;
		for (int ii = 0; ii < count-1; ii++) 
		{
			for (int jj = 0; jj < count - 1 - ii; jj++) 
			{
				if (r[jj] > r[jj + 1]) 
				{
					temp = r[jj];
					r[jj] = r[jj + 1];
					r[jj + 1] = temp;
				}
			}
		}
		
		//还钥匙
		
		for (int p = 0; p < count; p++) 
		{
			for (int q = 0; q < n; q++)
			{
				if (b[q] == false) 
				{
					a[q] = r[p];
					b[q] = true;
					break;
				}
			}
		}
		//拿钥匙
		int id;
		for (int w = 0; w < k; w++) 
		{
			if (s[w][1] == t) 
			{
				id = search(a, s[w][0], n);
				b[id] = false;
				a[id] = 0;
			}
		}
		//cout <<t<< " 时刻的状态为:" << endl;
		/*for (int r = 0; r < n; r++)
		{
			cout << a[r] << " ";
		}
		cout << endl;*/
	}
	for (int r = 0; r < n; r++)
	{
		cout << a[r] << " ";
	}
	
	system("pause");
	return 0;
}

接下来准备出一个关于sort算法的专题,详见专业课学习。 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值