题目描述见图片,如下
题目输入,见图片
题目分析
1.对操作进行模拟。对于操作顺序,题目中很明确给出每次还钥匙的时候,还到最左边的空位上,如果同时还钥匙,按照编号还,如果同时取和还,先还再取。那么这么一看就是三重结构体排序。对于结构体的构建,需要三个属性:操作时间,操作钥匙编号,操作标志。看好,这里是操作时间,并不是取钥匙时间和还钥匙时间,是放在一起啦,所以是操作时间。因此,对于每一个输入,都需要把输入变成两个操作,取钥匙和还钥匙。例如对于输入4 3 3 ,则分解成id=4,s=3,flag=0和id=4,e=3+3=6,flag=1.只要将全部输入变成全部操作后,才能利用结构体排序。结构体排序按照操作时间,操作标志,要是编号进行排序。
2.对钥匙进行模拟。操作顺序确定后,就要对钥匙进行模拟,无非就是取钥匙和还钥匙。在取钥匙时,对于相应的位置,置为0,代表空。还钥匙时从左到右遍历一遍,找到第一个空位置,将编号重置即可。
题目代码如下:
#include <iostream>
#include <algorithm>
#include <vector>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
struct key{
int kid,time,flag;//钥匙编号,操作时间,操作标志
};
bool compare1(key k1,key k2){
if(k1.time!=k2.time){//操作时间,小的先操作
return k1.time<k2.time;
}
else if(k1.flag!=k2.flag){//先还在取,还为1,取为0
return k1.flag>k2.flag;
}
else{
return k1.kid<k2.kid;//编号小的先处理
}
}
int main(int argc, char *argv[]) {
int N,K,len;
cin>>N>>K;
vector<key> mykey;
for(int i=0;i<K;i++){
int id,s,c;
cin>>id>>s>>c;
key k;
k.kid=id;
k.time=s;
k.flag=0;//借出
mykey.push_back(k);
k.kid = id;
k.time = s+c;
k.flag=1;//还回
mykey.push_back(k);
}
sort(mykey.begin(),mykey.end(),compare1);
int index[N+1];
for(int i=1;i<=N;i++){//数组初始化,模拟钥匙
index[i] = i;
}
for(int i=0;i<mykey.size();i++){
key k = mykey[i];
int id = k.kid,flag = k.flag;
if(flag==0){//借出
for(int j=1;j<=N;j++){//必须从左到右进行遍历
if(index[j]==id){
index[j]=0;
break;//不能少,找到第一个就结束了
}
}
}
else if(flag==1){//还钥匙
for(int mj=1;mj<=N;mj++){
if(index[mj]==0){
index[mj]=id;
break;
}
}
}
}
//去掉末尾的空格
cout<<index[1];
for(int i=2;i<=N;i++){
cout<<" "<<index[i];
}
return 0;
}