201709-2公共钥匙盒

转载自 http://blog.csdn.net/qq_30091945 https://blog.csdn.net/qq_30091945/article/details/78378223
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <iostream>
#include <vector> 
#include <algorithm> 
using namespace std;

typedef struct Action{                             
    int room;
    int time;       
    int type;                                      //0为还钥匙,1为取钥匙        
}Action;
 
int cmp(Action action1,Action action2){            //将action中记录从小到大进行类似基数排序
    if(action1.time < action2.time){               //先按照行为发生时间排序(时间早的在前) 
        return 1;
    }else if(action1.time == action2.time
	&& action1.type < action2.type){               //行为时刻相同,再按取还钥匙排序(同时有老师还取钥匙,还钥匙的在前) 
        return 1;
    }else if(action1.time == action2.time
	&& action1.type == action2.type
	&& action1.room < action2.room){               //时刻相同,行为相同,按钥匙序号排序 (序号小的在前) 
            return 1;   
    }
    return 0;                                      //否则action2排在前 
}

int N,K;                                           //N教室数 K老师人数 
int room,start,time;                               //教室号,上课时间,上课时长 
int state[1001];                                   //钥匙数组,因为下面是从state[1]开始定义钥匙编号,所以将数组最大长度设为1001 
vector<Action> actions;                            //定义动态数组 

int main()
{   
    while(cin>>N>>K){                              //输入教室数量N,老师数量K 
        for(int i = 1 ; i <= N ; i++){
            state[i] = i;                          //给每把钥匙编号 
        }
        
        for(int i = 0 ; i < K ; i++){              //将所有老师循环一遍 
            cin>>room>>start>>time;                //输入教室号,上课时间,上课时长 
            
            Action action;                         
            action.room = room;                    //要取的钥匙号 
            action.time = start;                   //取钥匙时间 
            action.type = 1;                       //每位老师先是取钥匙 
            actions.push_back(action);             //将代表取钥匙这一行为结构体放入数组 
            action.type = 0;                       //用完要还钥匙 
            action.time = start+time;              //还钥匙时间 
            actions.push_back(action);             //将代表还钥匙这一行为放入数组 ;此时数组中记录为2*k条 
		}
        
        sort(actions.begin(),actions.end(),cmp);   //比较action数组中记录 
        
        for(int i = 0 ; i < actions.size(); i++){  //遍历action中所有记录 
            Action action = actions[i];            //从第1个开始(数组下标为0) 
            
			if(action.type == 0){                  //如果是还钥匙   ;先判断action.type == 0表示当同时有多位老师还取钥匙时,保证先还后取 
                for(int j = 1 ; j <= N ; j++){     
                    if(state[j] == -1){            //如果j号钥匙被取走了;j是从左往右第一个被取走钥匙的编号,即第一个空挂钩 
                        state[j] = action.room;    //把钥匙放到第j个挂钩上 
                        break;                     //还完钥匙,要跳出for循环,不然所有空挂钩都会放上编号为action.room的钥匙 
                    }
                }
            }else{                                 //如果是取钥匙
				for(int j = 1 ; j <= N ; j++){     
                    if(state[j] == action.room){   //如果第j把钥匙是该老师要用的 
                        state[j] = -1;             //取走钥匙,标记该挂钩为空 
                        break;                     //如果已经找到符合的钥匙,就不用再遍历剩下的钥匙了 
                    }
                }
            }
            
        }
        
        for(int i = 1 ; i <= N ; i++){
            cout<<state[i]<<" ";                   //输出最终钥匙顺序 
        }
    }

    return 0;
}

呜呜呜,搞不定,,,找到这位大神编写的,一点一点加上注释顺下来的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值