本次模拟赛可以说是非常不理想,主要是之前的知识不会用,况且只知道个大概
1.Convention
题目描述:N 头奶牛,奶牛i在时刻ti到达。安排 M辆车,每辆最多能坐 C头奶牛。
安排奶牛乘车。当最后一头乘坐某辆车的奶牛到达的时候,这辆车就可以发车了。如果没有到达,那么其他要乘坐这辆车的奶牛就要等待到发车的时刻。
求等待时间最长的奶牛等待的时间的最小值。
当时可以说是不知道用什么,就直接写了个类似于模拟的代码,二分也不知道怎么用。
正解:先将牛到达的时间排序,通过判定 按此时间划分奶牛所需要的车辆数是否大于M 来检查这种方案是否合法,二分奶牛中的最大等待时间的最小值。
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int n,m,c,a[maxn];
bool check(int x) {
int car=1,f=a[1],p=0;
for(int i=1;i<=n;i++) {
if(++p>c)car++,f=a[i],p=1;
if(a[i]-f>x) car++,f=a[i],p=1;
}
return car<=m;
}
int main() {
cin>>n>>m>>c;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
int l=0,r=a[n]-a[1];
while(l<r) {
int mid=(l+r)>>1;
if(check(mid))r=mid;
else l=mid+1;
}
cout<<l<<"\n";
return 0;
}
2.Convention II
N 头牛排队吃草,编号为i的奶牛来排队的时刻为ai,吃草的时长为ti。当轮到一头牛吃完草后,会从队伍中选择编号最靠前的奶牛先吃。求所有奶牛在队伍里等待时间的最大值。
当时考虑到模拟,结果细节出错并且时间超限,当比赛结束后才发现模拟过程就是一个优先队列
正解:先按来到草地的时间排序,再利用优先队列,每次出队时都用当前时间减去入队时间更新最长等待时间,注意如果队列为空但还有奶牛没来时要直接把奶牛加进去,不能让队列为空
#include<bits/stdc++.h>
using namespace std;
struct cow{
int a,b,age;
bool operator < (cow x,cow y)
{
return x.age>y.age;
}
} c[100001];
bool cmp(cow x,cow y){
return x.a<y.a;
}
int n,cnt=2,now,ans;
priority_queue<cow> waiting;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
int t;
cin>>c[i].a>>c[i].b;
c[i].age=i;
}
sort(c+1,c+n+1,cmp);
waiting.push(c[1]);
now=c[1].a;
while(cnt<=n||!waiting.empty())
{
if(waiting.empty())
{
waiting.push(c[cnt]);
now=c[cnt].a;
cnt++;
}
cow f=waiting.top();
ans=max(ans,now-f.a);
waiting.pop();
now+=f.b;
for(cnt;c[cnt].a<=now&&cnt<=n;cnt++)
{
waiting.push(c[cnt]);
}
}
cout<<ans;
return 0;
}