201709-2 | |
试题名称: | 公共钥匙盒 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 有一个学校的老师共用N个教室,按照规定,所有的钥匙都必须放在公共钥匙盒里,老师不能带钥匙回家。每次老师上课前,都从公共钥匙盒里找到自己上课的教室的钥匙去开门,上完课后,再将钥匙放回到钥匙盒中。 输入格式 输入的第一行包含两个整数N, K。 输出格式 输出一行,包含N个整数,相邻整数间用一个空格分隔,依次表示每个挂钩上挂的钥匙编号。 样例输入 5 2 样例输出 1 4 3 2 5 样例说明 第一位老师从时刻3开始使用4号教室的钥匙,使用3单位时间,所以在时刻6还钥匙。第二位老师从时刻2开始使用钥匙,使用7单位时间,所以在时刻9还钥匙。 样例输入 5 7 样例输出 1 2 3 5 4 评测用例规模与约定 对于30%的评测用例,1 ≤ N, K ≤ 10, 1 ≤ w ≤ N, 1 ≤ s, c ≤ 30; |
满满的回忆。刚上大学的时候,写学校系统就写到这道题,现在刷ccf,才发现原来是道...
来看看我有没有进步吧
用map,套set,就像之前写那个训练二的第四题,电话本一样。
#include <bits/stdc++.h>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv)
{
int N,K;
cin>>N>>K;
int keys[N+1];
for(int i=1;i<=N;i++){
keys[i]=i;
}
set<int >times;
map<int,set<int> > x;//借
map<int,set<int> > y;//还
for(int i=0;i<K;i++){
int w,s,c;
cin>>w>>s>>c;
x[s].insert(w);
times.insert(s);
y[s+c].insert(w);
times.insert(s+c);
}
set<int>::iterator ita;
for(ita=times.begin();ita!=times.end();ita++){
int time=(*ita);
map<int,set<int> >::iterator its=y.find(time);
if(its!=y.end()){
set<int>::iterator ity;
int key;
for(ity=its->second.begin();ity!=its->second.end();ity++){
key=(*ity);
for(int i=1;i<=N;i++){
if(keys[i]==0){
keys[i]=key;
break;
}
}
}
}
map<int,set<int> >::iterator it=x.find(time);
if(it!=x.end()){
set<int>::iterator itx;
int key;
for(itx=it->second.begin();itx!=it->second.end();itx++){
key=(*itx);
for(int i=1;i<=N;i++){
if(keys[i]==key){
keys[i]=0;
break;
}
}
}
}
}
for(int i=1;i<=N;i++)
cout<<keys[i]<<" ";
cout<<endl;
return 0;
}
以前写的结构体。莎莎点的。
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
struct teacher
{
int key;
int start;
int time;
int end;
int flag=2;//2代表没拿钥匙 ,或者没还
};
int main(int argc, char** argv)
{
int N,K,flagup=0,flaghuan=0,flagjie=0;
cin>>N>>K;
teacher x[K];
int a[N+1];
for(int i=0; i<K; i++)
{
cin>>x[i].key>>x[i].start>>x[i].time;
x[i].end=x[i].start+x[i].time;
}
for(int i=0; i<N+1; i++)
{
a[i]=i;
}
for(int t=1;;t++)
{
flagup=0;
for(int i=0;i<K;i++)
{
if(t==x[i].start) //拿钥匙
{
x[i].flag=3;
flagjie=1;
}//表示钥匙准备被拿了
if(t==x[i].end)
{
x[i].flag=1,flaghuan=1;//表示准备还钥匙
}
}
int flag=1;
if(flaghuan==1)
{
flaghuan=0;
while(flag==1)
{
int temp=100000000;
flag=0;//只要有人还要还钥匙flag就会变成1
for(int i=0; i<K; i++)
{
if(x[i].key<temp&&x[i].flag==1)
{
temp=x[i].key; //每次从需要还钥匙的人里面找一个序号最小的
flag=1;
}
}if(flag==1){
for(int i=0; i<K; i++)
{
if(temp==x[i].key&&x[i].flag==1)
//防止前面已经还过的来干扰!!!!!!!!!这个de了一个小时
{
x[i].flag=0;
break;
}
}
//把这一轮换钥匙的人踢了,免得下一轮又选了它
for(int i=1; i<N+1; i++)
{
if(a[i]==0)
{
a[i]=temp;
break;
}
}
}
}
}
if(flagjie==1)
{
flagjie=0;
for(int i=0; i<K; i++)
{
if(x[i].flag==3)
{
for(int j=1;j<N+1;j++){ //全都要扫一遍,防止同时多人借
if(a[j]==x[i].key)
{
a[j]=0;break; //找到正确的key位 !!!!!!这个de了半个小时
}
} //a[x[i].key]=0;不能这样写,因为位置已经乱了,借了几次之后
x[i].flag=2;
}
}
}//而且借要写在还后面 ,而且借了要变回2
//可以不这样,可以先找最后归还的时间,循环截止点就找到了,不用每次都扫一遍
for(int i=0; i<K; i++)
{
if(x[i].flag!=0)
{
flagup=1;
break;
}
}
if(flagup==0)break;
}
for(int i=1; i<N+1; i++)
{
cout<<a[i]<<" ";
}
return 0;
}