ccf公共钥匙盒

题目描述见图片,如下
这里写图片描述
题目输入,见图片
这里写图片描述
题目分析
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;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值