这道题理解不难,但是实现真的。。。
网上没有答案,也不知道自己错在哪里了,于是自己测试样例找错误,最后终于找对了。
我的大致思想就是纯模拟(这道题除了模拟,应该没有其他做法,有的话,请大佬告诉我)。
利用一个vector模拟钥匙盒,然后模拟取放。当V[i]为负时,代表盒子中的第i个位置此时没有钥匙。
利用结构体,来存放每条指令的钥匙标号和开始使用时间与结束时间。然后将所有的指令按照取钥匙的起始时间进行排序,然后开始模拟。
代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
using namespace std;
int vis[2005];
int flag[2005];
struct Key
{
int id;
int st;
int ed;
} key[2005],kk[2005],d[2005];
int cmp(Key a,Key b)
{
return a.st<b.st;
}
int cmp2(Key a,Key b)
{
if(a.ed==b.ed)
return a.id<b.id;
return a.ed<b.ed;
}
int main()
{
int n,k;
scanf("%d%d",&n,&k);
vector<int>V;
V.clear();
for(int i=1; i<=n; i++)
{
V.push_back(i);
}
memset(vis,0,sizeof(vis));//第i条指令有效
memset(flag,1,sizeof(flag));//第i把钥匙放在盒子内
int c;
for(int i=1; i<=k; i++)
{
scanf("%d%d%d",&key[i].id,&key[i].st,&c);
key[i].ed=key[i].st+c;
}
sort(key+1,key+k+1,cmp);
int ans=0,t=0;
for(int i=1; i<=k; i++)
{
ans=0;
for(int j=1; j<i; j++)
{
if(vis[j])continue;
if(key[j].ed<=key[i].st)
{
vis[j]=1;//指令无效
d[ans].id=key[j].id;
d[ans++].ed=key[j].ed;
flag[key[j].id]=1;
}
}
sort(d,d+ans,cmp2);
t=0;
if(ans)
{
for(int j=0; j<V.size()&&t<ans; j++)
{
if(V[j]<0&&d[t].id)
{
V[j]=d[t++].id;
}
}
}
for(int j=0; j<V.size(); j++)
{
if(V[j]==key[i].id)
{
flag[key[i].id]=0;//拿出去
V[j]=-1;
break;
}
}
}
ans=0;
for(int i=1; i<=k; i++)
{
if(!vis[i])kk[ans++]=key[i];
}
sort(kk,kk+ans,cmp2);
for(int i=0; i<ans; i++)//剩下的钥匙按照结束时间进行放钥匙
{
if(!flag[kk[i].id])
{
for(int j=0; j<V.size(); j++)
{
if(V[j]<0)
{
V[j]=kk[i].id;
flag[kk[i].id]=1;
break;
}
}
}
}
printf("%d",V[0]);
for(int j=1; j<V.size(); j++)
{
printf(" %d",V[j]);
}
printf("\n");
}
/*
10 10
1 1 14
3 3 12
1 15 12
2 7 20
3 18 12
4 21 19
5 30 9
6 3 5
7 8 9
8 6 5
6 8 7 1 5 2 3 4 9 10
*/
模拟题就要想得周全