题目描述
解题思路
思路一: 简单粗暴的模拟,以时间为线索,将取钥匙和还钥匙的时间进行进行排序,然后按时间循环,到达某时间点时执行取钥匙或者还钥匙操作;
思路二: 以取还钥匙的动作为线索,当时间跨度大时可以省去很多不必要的循环;
代码
思路一:
// 思路一
/*公共钥匙盒
思路:设置两个数组,一个按取钥匙的时间进行排序,
再一个按还钥匙的时间进行排序,按着时间走进行取还操作
*/
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
const int N=1001;
int keybox[N];
struct state{
int key;
int start;
int end;
}intial[N],final[N];
bool cmp1(state s1,state s2){
return s1.start<s2.start;
}
bool cmp2(state s1,state s2){
if(s1.end!=s2.end)
return s1.end<s2.end;
else
return s1.key<s2.key;
}
int main(){
int n,k,s,w,c,maxtime=0;
cin>>n>>k;
//初始化钥匙盒
for(int i=0;i<n;i++){
keybox[i]=i+1;
}
//输入数据
for(int i=0;i<k;i++){
cin>>w>>s>>c;
intial[i].key=w;
intial[i].start=s;
intial[i].end=c;
final[i].key=w;
final[i].start=s;
final[i].end=s+c;
maxtime=(maxtime>final[i].end)?maxtime:final[i].end;
}
//按时间顺序取换钥匙
sort(intial,intial+k,cmp1);
sort(final,final+k,cmp2);
int flag_f=0,flag_i=0;
for(int i=1;i<=maxtime;i++){
//先还
for(int m=flag_f;m<k;m++){
if(final[m].end==i){
for(int t=0;t<n;t++){
if(keybox[t]==0){
//还钥匙
keybox[t]=final[m].key;
// cout<<"还钥匙"<<final[m].key<<endl;
flag_f++;
break;
}
}
//一次可能还多把钥匙,如果最小的时间已经超过当前的时间,则可以跳出循环
}
if(final[m].end>i) break;
}
//再取
for(int m=flag_i;m<k;m++){
if(intial[m].start==i){
for(int t=0;t<n;t++){
if(keybox[t]==intial[m].key){
keybox[t]=0;
// cout<<"借钥匙"<<intial[m].key<<endl;
flag_i++;
break;
}
}
}
if(intial[m].start>i) break;
}
}
for(int i=0;i<n;i++){
cout<<keybox[i]<<" ";
}
cout<<endl;
return 0;
}
思路二
https://blog.youkuaiyun.com/tigerisland45/article/details/79511144
ps:写代码真是巨坑的事,总是错了n次之后发现死在莫名其妙的地方,心累。。。