CCF认证 - 201709-2 - 公共钥匙盒 C++代码实现 (plus 详细注释)(100分)

这里的思路是:
1、首先初始化一个起始钥匙盒keybox,用来盛放每次归还/借出钥匙后的钥匙排布状态,初始化为1 ~ n表示钥匙的位置,若钥匙借出,则对应位置置为0;
2、建立结构体数组k_u(为了对二维数组进行分字段排序)录入钥匙的存取情况;
3、对k_u数组以归还时间k_u[i].end为第一关键字,以k_u[i].key_no为第二关键字进行排序,这样做的好处是当需要归还钥匙时,可以直接按归还的时间先后以及钥匙编号由小到大的顺序归还,不必再进行排序;
4、建立时刻变量time,表示时间的推移(最外层循环);
5、内循环中,在某个时刻遍历数组k_u,看是否发生钥匙归还or借出,当钥匙需要归还时,遍历钥匙盒keybox,若发现有位置的状态为0,则直接赋值当前归还钥匙的编号,表示钥匙已经归还,若钥匙需要借出,则对应k_u[i].key_no置为0即可。
代码如下:(关键是结构体数组的分字段排序)

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
struct key_using{
	int key_no;
	int start;
	int end;
}k_u[1000];//定义k_u结构体数组,key_no表示钥匙编码,start表示钥匙开始借用的时间,
		//end表示钥匙的归还时间;
bool cmp(key_using m, key_using n) {
	if(m.end == n.end)
		return m.key_no < n.key_no;
	return m.end < n.end;
}//结构体的end为第一关键字,key_no为第二关键字;
int main(){
		int keybox[1000] = {0}; 
		int n, k, w, s, c, temp, time = 0;
		scanf("%d%d", &n, &k);
		for(int i = 0; i < n; i++)
			keybox[i] = i + 1;//钥匙盒进行初始化;
		for(int i = 0; i < k; i++) {
			scanf("%d%d%d", &w, &s, &c);
			k_u[i].key_no = w;
			k_u[i].start = s;
			k_u[i].end = s + c;
		}
		sort(k_u, k_u + k, cmp);//排序; 
	
				/*	for(int j = 0; j < k; j++)
					{
						printf("%-3d%-3d%-3d", k_u[j].key_no, k_u[j].start, k_u[j].end);
						printf("\n");
					}//测试输出;*/ 
		while(time <= k_u[k - 1].end) {
			for(int i = 0; i < k; i++) {
				if(time == k_u[i].end)//如果到了归还某把钥匙的时刻;
					for(int j = 0; j < n; j++)
						if(keybox[j] == 0) {
							keybox[j] = k_u[i].key_no;
							break;
						}//则遍历钥匙盒,若有空位,则把钥匙放入;
				if(time == k_u[i].start)//如果到了借出某把钥匙的时刻;
					for(int j = 0; j < n; j++)
						if(keybox[j] == k_u[i].key_no) {
							keybox[j] = 0;
							break;
						}//则遍历钥匙盒,找到需借出的钥匙并将其取出;
			}//保证了同一个时刻先放再取;
			time++;
		}
		for(int i = 0; i < n; i++)
			printf("%d ", keybox[i]);
		return 0;
	}
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值