USACO18DEC模拟赛


本次模拟赛可以说是非常不理想,主要是之前的知识不会用,况且只知道个大概

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;
}

Mooyo Mooyo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值