ccf-csp - 2017-09-02 公共钥匙盒

已经很久没有刷过题了,上一次更新博客还是两年前,哈哈,我想不是必须得通过csp认证我也不会再刷题了,emmmmm, 貌似要从头开始了


题目:有一个学校的老师共用N个教室,按照规定,所有的钥匙都必须放在公共钥匙盒里,老师不能带钥匙回家。每次老师上课前,都从公共钥匙盒里找到自己上课的教室的钥匙去开门,上完课后,再将钥匙放回到钥匙盒中。
  钥匙盒一共有N个挂钩,从左到右排成一排,用来挂N个教室的钥匙。一串钥匙没有固定的悬挂位置,但钥匙上有标识,所以老师们不会弄混钥匙。
  每次取钥匙的时候,老师们都会找到自己所需要的钥匙将其取走,而不会移动其他钥匙。每次还钥匙的时候,还钥匙的老师会找到最左边的空的挂钩,将钥匙挂在这个挂钩上。如果有多位老师还钥匙,则他们按钥匙编号从小到大的顺序还。如果同一时刻既有老师还钥匙又有老师取钥匙,则老师们会先将钥匙全还回去再取出。
  今天开始的时候钥匙是按编号从小到大的顺序放在钥匙盒里的。有K位老师要上课,给出每位老师所需要的钥匙、开始上课的时间和上课的时长,假设下课时间就是还钥匙时间,请问最终钥匙盒里面钥匙的顺序是怎样的?


解题思路:该题核心思想是把取钥匙和放钥匙看成是两个动作,按时间点来操作,定义一个类,按照其结束时间进行排序,某一时间既存在放钥匙,也存在取钥匙时,先放后取,动作相同时,先对编号小的钥匙进行操作


#include 
#include 
#include 
using namespace std;

class Key{
	public:
		int number;
		int start;
		int end;
};

int n,k;
Key s1[1005], s2[1005];
int index1[1005], index2[1005];

bool cmp1(Key const &k1, Key const &k2){
	if(k1.end < k2.end)
		return true;
	else if(k1.end == k2.end && k1.number < k2.number)
		return true;
	else
		return false;
}

bool cmp2(Key const &k1, Key const &k2){
	if(k1.start < k2.start)
		return true;
	else if(k1.start == k2.start && k1.number < k2.number)
		return true;
	else
		return false;
}

void Pretreatment(){
	memset(s1,0,sizeof(s1));
	memset(s2,0,sizeof(s2));
	for(int i = 1; i <= n; i++){
		index1[i] = i;
		index2[i] = i;
	}
	for(int i = 0; i < k; i++){
		int w,s,c;
		cin>>w>>s>>c;
		s1[i].number = s2[i].number = w;
		s1[i].start = s2[i].start = s;
		s1[i].end = s2[i].end = s + c;
	}
	sort(s1,s1+k,cmp1);
	sort(s2,s2+k,cmp2);
}

int find(){
	int i = 1;
	while(index1[i] > 0)
		i++;
	return i;
}

void Print(){
	for(int i = 1; i < n; i++)
			cout<>n){
		cin>>k;
		Pretreatment();
		for(int i = 0, j = 0; i < k; i++){
			int time = s1[i].end;
			while(s2[j].start < time && j < k){
				int pos = index2[s2[j].number];
				index1[pos] = -1;
				index2[s2[j].number] = -1;
				j++;
			}
			int t = find();
			index1[t] = s1[i].number;
			index2[s1[i].number] = t;
			// Print();
		}
		Print();
	}
	return 0;
}

你可能感兴趣的:(ccf-csp认证)