3-3模拟赛补题报告

题目描述

一场别开生面的牛吃草大会就要在 Farmer John 的农场举办了!

世界各地的奶牛将会到达当地的机场,前来参会并且吃草。具体地说,有 N 头奶牛到达了机场(1≤N≤105),其中奶牛 i 在时间 ti​(0≤ti​≤109)到达。Farmer John 安排了 M(1≤M≤105)辆大巴来机场接这些奶牛。每辆大巴可以乘坐 C 头奶牛(1≤C≤N)。Farmer John 正在机场等待奶牛们到来,并且准备安排到达的奶牛们乘坐大巴。当最后一头乘坐某辆大巴的奶牛到达的时候,这辆大巴就可以发车了。Farmer John 想要做一个优秀的主办者,所以并不想让奶牛们在机场等待过长的时间。如果 Farmer John 合理地协调这些大巴,等待时间最长的奶牛等待的时间的最小值是多少?一头奶牛的等待时间等于她的到达时间与她乘坐的大巴的发车时间之差。

输入格式

输入的第一行包含三个空格分隔的整数 N,M,和 C。第二行包含 N 个空格分隔的整数,表示每头奶牛到达的时间。

输出格式

输出一行,包含所有到达的奶牛中的最大等待时间的最小值。

输入输出样例

输入

6 3 2
1 1 10 14 4 3

输出

4

思路

求最大值的最小值,可以使用二分答案.

check:将到达时间排序,对于当前答案遍历,如果此车等待时间超出或人数超出,就新开一辆,最后看车是否够用.

AC代码

#include<bits/stdc++.h>
using namespace std;
int n,t[100005],m,c;
int main(){
	cin>>n>>m>>c;
	for(int i=1;i<=n;i++){
		cin>>t[i];
	}
	sort(t+1,t+1+n);
	int l=0,r=t[n];
	while(l<r){//1 1 3 4 10 14
		int mid=(l+r)/2;
		int cnt=1,tcn=1,tmp=t[1];
		for(int i=2;i<=n;i++){	
			if(t[i]-tmp>mid||tcn==c){
				cnt++;
				tmp=t[i];
				tcn=1;
			}
			else{
				tcn++;
			}
			//cout<<tmp<<' '<<tcn<<endl;
		}
		//cout<<mid<<' '<<l<<' '<<r<<' '<<cnt<<endl;
		if(cnt>m){
			l=mid+1;
		}
		else{
			r=mid;
		}
		
	}
	cout<<l;
	return 0;
}

题目描述

虽然在接机上耽误了挺长时间,Farmer John 为吃草爱好牛们举行的大会至今为止都非常顺利。大会吸引了世界各地的奶牛。

然而大会的重头戏看起来却给 Farmer John 带来了一些新的安排上的困扰。他的农场上的一块非常小的牧草地出产一种据某些识货的奶牛说是世界上最美味的品种的草。因此,所有参会的 N 头奶牛(1≤N≤105)都想要品尝一下这种草。由于这块牧草地小到仅能容纳一头奶牛,这很有可能会导致排起长龙。

Farmer John 知道每头奶牛i计划到达这块特殊的牧草地的时间 ai​,以及当轮到她时,她计划品尝这种草花费的时间 ti​。当奶牛i 开始吃草时,她会在离开前花费全部 ti​ 的时间,此时其他到达的奶牛需要排队等候。如果这块牧草地空出来的时候多头奶牛同时在等候,那么资历最深的奶牛将会是下一头品尝鲜草的奶牛。在这里,恰好在另一头奶牛吃完草离开时到达的奶牛被认为是“在等待的”。类似地,如果当没有奶牛在吃草的时候有多头奶牛同时到达,那么资历最深的奶牛是下一头吃草的奶牛。

请帮助 FJ 计算所有奶牛中在队伍里等待的时间(ai​ 到这头奶牛开始吃草之间的时间)的最大值。

输入格式

输入的第一行包含 N。以下 N 行按资历顺序给出了 N 头奶牛的信息(资历最深的奶牛排在最前面)。每行包含一头奶牛的 ai​ 和 ti​。所有的 ti​ 为不超过 104 的正整数,所有 ai​ 为不超过 109 的正整数。

输出格式

输出所有奶牛中的最长等待时间。

输入输出样例

输入

5
25 3
105 30
20 50
10 17
100 10

输出

10

思路

直接模拟即可

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=100005;
int n,vis,ans;
struct node{
	int a,t,id,ed;
	bool operator <(const node x)const
	{
	if(x.a<a)
	return 0;
	if(x.a>a)
	return 1;
	return x.id>id;
	}
}c[maxn];
priority_queue<pair<int,int> >q;

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&c[i].a,&c[i].t);
		c[i].id=i;
	}
	sort(c+1,c+1+n);
	int x;
	vis=c[1].a+c[1].t;
	for(int i=2;i<=n;i++)
	{
		if(c[i].a>=vis)
		{
			if(!q.empty())
			{
				int x=q.top().second;
				q.pop();
				ans=max(ans,vis-c[x].a);
				vis+=c[x].t;
				if(vis<c[i].a)
				--i;
				else			
				q.push(make_pair(-c[i].id,i));
			}else// no need to wait
				vis=c[i].a+c[i].t;
		}
		else
		{
			q.push(make_pair(-c[i].id,i));
		}
	}
	while(!q.empty())
	{
		int x=q.top().second;
		q.pop();
		ans=max(vis-c[x].a,ans);
		vis+=c[x].t;
	}
	printf("%d",ans);
	return 0;
}

题目描述

由于手上(更确实的,蹄子上)有大把的空余时间,Farmer John 的农场里的奶牛经常玩电子游戏消磨时光。她们最爱的游戏之一是基于一款流行的电子游戏 Puyo Puyo 的奶牛版;名称当然叫做 Mooyo Mooyo。

Mooyo Mooyo 是在一块又高又窄的棋盘上进行的游戏,高 N(1≤N≤100)格,宽 1010 格。 这是一个 N=6 的棋盘的例子:

0000000000
0000000300
0054000300
1054502230
2211122220
1111111223

每个格子或者是空的(用 00 表示),或者是九种颜色之一的干草捆(用字符 1…91…9 表示)。重力会使得干草捆下落,所以没有干草捆的下方是 00。

如果两个格子水平或垂直方向直接相邻,并且为同一种非 00 颜色,那么这两个格子就属于同一个连通区域。任意时刻出现至少 K 个格子构成的连通区域,其中的干草捆就会全部消失,变为 00。如果同时出现多个这样的连通区域,它们同时消失。随后,重力可能会导致干草捆向下落入某个变为 00 的格子。由此形成的新的布局中,又可能出现至少 K 个格子构成的连通区域。若如此,它们同样也会消失(如果又有多个这样的区域,则同时消失),然后重力又会使得剩下的方块下落,这一过程持续进行,直到不存在大小至少为K的连通区域为止。

给定一块 Mooyo Mooyo 棋盘的状态,输出这些过程发生之后最终的棋盘的图案。

输入格式

输入的第一行包含 N 和 K(1≤K≤10N)。以下 N 行给出了棋盘的初始状态。

输出格式

输出 N 行,描述最终的棋盘状态。

输入输出样例

输入 

6 3
0000000000
0000000300
0054000300
1054502230
2211122220
1111111223

输出 

0000000000
0000000000
0000000000
0000000000
1054000000
2254500000

思路

同样直接模拟,找联通块并删掉,然后将上方不为空的方格下移

代码

#include<bits/stdc++.h>
using namespace std;
bool biaoji[101][11],f;
int sum,n,k;
char ch[101][11];
int q[4]= {0,1,0,-1};
int w[4]= {1,0,-1,0};
void dfs(int x,int y,int s) {
	biaoji[x][y]=1;
	for(int i=0; i<=3; i++) {
		int xx=x+q[i];
		int yy=y+w[i];
		if(biaoji[xx][yy]==0&&ch[xx][yy]==s) {
			sum++;
			dfs(xx,yy,s);
		}
	}
}
void xialuo() {
	for(int i=n; i>=1; i--) {
		for(int j=1; j<=10; j++) {
			if(ch[i][j]!='0') {
				int k=i;
				while(ch[k+1][j]=='0'&&k<=n) {
					k++;
				}
				if(k!=i) {
					ch[k][j]=ch[i][j];
					ch[i][j]='0';
				}
			}
		}
	}
}
int main() {
	cin>>n>>k;
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=10; j++) {
			cin>>ch[i][j];
		}
	}
	f=1;
	while(f) {
		f=0;
		for(int i=1; i<=n; i++) {
			for(int j=1; j<=10; j++) {
				if(ch[i][j]!='0') {
					sum=1;
					memset(biaoji,false,sizeof(biaoji));
					dfs(i,j,ch[i][j]);
					if(sum>=k) {
						for(int xxx=1; xxx<=n; xxx++) {
							for(int xxxx=1; xxxx<=10; xxxx++) {
								if(biaoji[xxx][xxxx]) {
									ch[xxx][xxxx]='0';
								}
							}
						}
						f=1;
					}
				}
			}
		}
		if(f==1) {
			xialuo();
		}
	}
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=10; j++) {
			cout<<ch[i][j];
		}
		cout<<endl;
	}
	return 0;
}

  • 18
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值