CSP2021-S T1 廊桥分配

这其实是一道贪心的题目,然而官方数据很水导致n^2也能卡过
题目廊桥分配
答案要的是分配出的停放飞机的最大值,但是我们并不知道哪一种方法最优,所以我们可以把国内机场和国际机场分配x个廊桥时的最大停放飞机求出来,然后从分配机场数0到n枚举一遍求出最大值。
至于求解廊桥里的飞机停放数目,则可以建一个优先队列和一个廊桥数组来求解。
而优化代码则是建立两个优先队列,一个是为了存放能进入的廊桥的标号,一个是为了存放最后离开的时间,与一直到达时间作为比较。

点击查看代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<queue>
using namespace std;

#define MA 100005

int n,m1,m2;
int pm1[MA]={0},tt1=0;
int pm2[MA]={0},tt2=0;
int en1[MA]={0},en2[MA]={0};
int as1[MA]={0},as2[MA]={0};
struct node1 {
	int fr,to;
	bool operator < (const node1 x)const {
		return fr>x.fr;
	}
};
struct node2 {
	int to,num;
	bool operator < (const node2 x)const {
		return to>x.to;
	}
};
priority_queue<node1>s1;
priority_queue<node2>s2;
bool cmp(int x,int y) {
	return x>y;
}
void rd1(int m,int &tot) {
	int i;
	int fr,to;
	
	while(!s1.empty())
		s1.pop();
//	while(!s2.empty())
//		s2.pop();
	
	for(i=1;i<=m;++i) {
		scanf("%d%d",&fr,&to);
		s1.push((node1){fr,to});
	}
	node1 x;
	//node2 y;
	//int num;
	bool flag;
	while(!s1.empty()) {
		x=s1.top();
		s1.pop();
		//printf("[%d,%d]\n",x.fr,x.to);
		//flag=0;
		for(i=1;i<=tot;++i)
			if(x.fr>=en1[i]) {
				en1[i]=x.to;
				++pm1[i];
				//flag=1;
				break;
			}
		if(i>tot) {
			++tot;
			++pm1[tot];
			en1[tot]=x.to;
		}
		//printf("%d %d]\n",i,tot);
	}
	//sort(pm1+1,pm1+1+m,cmp);
	for(i=1;i<=tt1;++i) {
		as1[i]=as1[i-1]+pm1[i];
	}
	return;
}
void rd2(int m,int &tot) {
	int i;
	int fr,to;
	
	while(!s1.empty())
		s1.pop();
//	while(!s2.empty())
//		s2.pop();
	
	for(i=1;i<=m;++i) {
		scanf("%d%d",&fr,&to);
		s1.push((node1){fr,to});
	}
	node1 x;
	//node2 y;
	//int num;
	bool flag;
	while(!s1.empty()) {
		x=s1.top();
		s1.pop();
		//printf("<>%d %d\n",x.fr,x.to);
		//flag=0;
		for(i=1;i<=tot;++i)
			if(x.fr>=en2[i]) {
				en2[i]=x.to;
				++pm2[i];
				//flag=1;
				break;
			}
		if(i>tot) {
			++tot;
			++pm2[tot];
			en2[tot]=x.to;
		}
	}
	//sort(pm2+1,pm2+1+m,cmp);
	for(i=1;i<=tt2;++i) {
		as2[i]=as2[i-1]+pm2[i];
	}
	return;
}
void print() {
	int i;
	puts("");
	for(i=1;i<=tt1;++i) {
		printf("%d ",pm1[i]);
	}
	puts("");
	puts("");
}
int main() {
	//freopen("airport.in","r",stdin);
	//freopen("airport.out","w",stdout);
	//int n,m1,m2;
	scanf("%d%d%d",&n,&m1,&m2);
	
	rd1(m1,tt1);
	rd2(m2,tt2);
	
	int ans=0,i;
	for(i=tt1+1;i<=n;++i) {
		as1[i]=as1[tt1];
	}
	for(i=tt2+1;i<=n;++i) {
		as2[i]=as2[tt2];
	}
	
	
	//print();
	
	
	for(i=0;i<=n;++i) {
		ans=max(as1[i]+as2[n-i],ans);
		//printf("%d\n",ans);
		//printf("[%d,%d]\n",as1[i],as2[i]);
	}
	printf("%d\n",ans);
	return 0;
}
优化代码
点击查看代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<queue>
using namespace std;

#define MA 100005

int n,m1,m2;
int pm1[MA]={0},tt1=0;
int pm2[MA]={0},tt2=0;
int en1[MA]={0},en2[MA]={0};
int as1[MA]={0},as2[MA]={0}; 
struct node1 {
	int to,fr;
};
struct node2 {
	int to,num;
	bool operator < (const node2 x)const {
		return to>x.to;
	}
};
priority_queue<node2>s1;
priority_queue< int,vector<int>,greater<int> >s2;
bool cmp(int x,int y) {
	return x>y;
}
bool cmp2 (node1 x,node1 y) {
	return x.fr<y.fr;
}
node1 y[MA];
void rd(int m,int &tot,int *as) {
	int i;
	int fr,to;
	
	while(!s1.empty())
		s1.pop();
	while(!s2.empty())
		s2.pop();
	
	for(i=1;i<=m;++i) {
		scanf("%d%d",&y[i].fr,&y[i].to);
		s2.push(i);
	}
	sort(y+1,y+1+m,cmp2);
	int sz=0;
	for(i=1;i<=m;++i) {
		if(sz) {
			while(sz && y[i].fr>s1.top().to) {
				--sz;
				s2.push(s1.top().num);
				s1.pop();
			}
		}
		if(!s2.empty()) {
			tot=max(tot,s2.top());
			++as[s2.top()];
			s1.push((node2){y[i].to,s2.top()});
			s2.pop();
			++sz;
		}
	}
	for(i=1;i<=tot;++i) {
		as[i]=as[i-1]+as[i];
	}
	return;
}
void print() {
	int i;
	puts("");
	for(i=1;i<=tt1;++i) {
		printf("%d ",pm1[i]);
	}
	puts("");
	puts("");
}
int main() {
	//freopen("airport.in","r",stdin);
	//freopen("airport.out","w",stdout);
	scanf("%d%d%d",&n,&m1,&m2);
	
	rd(m1,tt1,as1);
	rd(m2,tt2,as2);
	
	int ans=0,i;
	for(i=tt1+1;i<=n;++i) {
		as1[i]=as1[tt1];
	}
	for(i=tt2+1;i<=n;++i) {
		as2[i]=as2[tt2];
	}

	//print();
	
	for(i=0;i<=n;++i) {
		ans=max(as1[i]+as2[n-i],ans);
	}
	printf("%d\n",ans);
	return 0;
}
posted @ 2021-11-01 18:03  WE-R  阅读(195)  评论(0)    收藏  举报