(算法练习)——201709-2公共钥匙盒(CCF模拟)

这一题简直要吐血= =从昨天下午开始搞,写了三版,想了数组、队列、结构体,但总是有步骤不对,好像哪里没有整合到一块,零零散散的感觉。。
今天睡一觉起来就觉得有思路了,吃过饭写了一会,可算搞出来了~(PS:这要是考试可怎么办= =)
说下思路:
1、用结构体存每个ID的信息,主体是time,想要让它们顺着一维的时间去执行,打个比方,编号1在10拿钥匙,拿了7小时,也就是17放回钥匙,那么就记录两条信息,一个time为10,一个time为17;同时再用signal记录下这个时刻是拿钥匙还是放钥匙(代码里signal = 1,表示拿钥匙,signal = 0表示还钥匙)
2、结构体需要再存放一个op,也就是此时此刻拿钥匙的时候,这个ID所在的位置,这句话是理解这一题的关键!!钥匙来来去去,但位置就那么几个,变化的是空出来的位置!!
3、用优先队列来模拟整个拿钥匙、放钥匙的过程,因为题目说每次放钥匙的时候,总是从左边(从小的剩余位置开始考虑),优先队列让小数优先级在前,自然满足~
4、给这些结构体排序,按照时间从小到大、时间相同,按先放钥匙再拿钥匙,都相同,按编号从小开始处理
5、单弄一个数组ans[],用来存每次变动完,有钥匙的位置存放的钥匙ID(开始想用map,但map不熟,就还用结构体了)

AC代码:

#include <stdio.h>
#include <queue>
#include <algorithm>
using namespace std;

struct node{
	int id,time,op;    
	int signal;     //signal = 1,表示拿钥匙,signal = 0表示还钥匙
}G[2010];

bool cmp(node a,node b){
	if(a.time != b.time){
		return a.time < b.time;    //按时间从小到大排序 
	}
	else if(a.signal != b.signal && a.time == b.time){
		return a.signal < b.signal;     //按先还再取 
	}
	else if(a.signal == b.signal && a.time == b.time && a.id != b.id){
		return a.id < b.id;      //都一样按编号从小到大 
	}
}

int main(){
	int N,K;
	int sympol = 0;  //计数用 
	int x,y,z;
	int ans[1000];
	scanf("%d %d",&N,&K);
	for(int i = 1;i<=N;i++){   //初始认为每个位置放各自编号 
		ans[i] = i;
	}
	for(int i = 0;i <K;i++){
		scanf("%d %d %d",&x,&y,&z);
		G[sympol].id = x;
		G[sympol].time = y;
		G[sympol].signal = 1;
		G[sympol].op = x;    //初始默认拿钥匙时在自己位置 
		sympol++;
		G[sympol].id = x;
		G[sympol].time = y+z;
		G[sympol].signal = 0;
		sympol++; 
	}
	sort(G,G+sympol,cmp);
	priority_queue <int,vector<int>,greater<int> > q;
	for(int i = 0;i <sympol;i++){
		if(G[i].signal == 1){   //拿钥匙 
			q.push(G[i].op);   //把位置入队列 
		}
		else{
			int t = q.top();    //还钥匙  
			ans[t] = G[i].id;    //t位置放新的id 
			G[i].op = t;       //更新它的位置 
			for(int j = i;j < sympol;j++){   //往后如果有再拿钥匙,变更存放位置 
				if(G[i].id == G[j].id && G[j].signal == 1){
					G[j].op = G[i].op;
					break;
				}
			} 
			q.pop();     //还好钥匙,出队 
		}
	}
	
	for(int i = 1;i <=N;i++){
		printf("%d ",ans[i]);
	}
}
发布了212 篇原创文章 · 获赞 6 · 访问量 6382

猜你喜欢

转载自blog.csdn.net/weixin_42377217/article/details/104353318
今日推荐