【SP-S第一题】题解

CSP-S第一题题解:

题目传送门——
题解:
假设现在已经知道有两个数组:ans1和ans2。
ans1保存的是国内区有i(0<=i<=n)个廊桥时能装下的飞机数。
ans2保存的是国际区有i(0<=i<=n)个廊桥时能装下的飞机数。
那么答案是是多少呢?
很明显 a n s = m a x ( a n s 1 [ i ] + a n s [ n − i ] , a n s ) ( 0 < = i < = n ) ans=max(ans1[i]+ans[n-i],ans)(0<=i<=n) ans=max(ans1[i]+ans[ni],ans)(0<=i<=n)
那么问题就集中在了如何求出ans1和ans2。
可以先想想,我考试时就卡在后面了;


∗ ∗ — — — — — — — — — — — — — — — — — — 华 丽 的 答 案 分 割 线 — — — — — — — — — — — — — — — ∗ ∗ **——————————————————华丽的答案分割线———————————————** 线




因为先到先得,并且多加一个廊桥后不会影响之前已经进入的飞机;
所以 我们考虑维护未进入廊桥的飞机。

当一架飞机离开后,取出这架飞机离开后最先到达的未进入廊桥的飞机。以此类推,直到没有飞机能进入廊桥。经过这一轮操作后,就可以得到:当多一个廊桥后,能够多进入几架飞机数ct。
所以ans1=ans[i-1]+ct(ct为能多进入的飞机数)
有点迷糊?
先看第一个样例数据 题目有图懒得画
当只有一个廊桥(给他一个名字叫一号)时能进入的飞机有:1,3,5号飞机
而加一个廊桥(给他一个名字叫二号)后,原先的一号廊桥不会受影响。新来的飞机都在二号廊桥排。(千万不要用队列模拟,否则很难看出来)
那么我们就可以用set来实现 没学set别打我
set的有序性和方便插入,删除的性质可以方便我们实现。 你能手写一个更NB的当我没说
代码:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int n,m1,m2;
struct p{
	int s,e;//s为降落时间,e为起飞时间 
	bool operator <(const p &a)const
	{
		return s<a.s;
	}
};
const int N=1e5+5;
p a1[N];//保存国内的 
p a2[N];//保存国际的 
set<p> s;
int ans1[N];
int ans2[N];
int main()
{
	scanf("%d%d%d",&n,&m1,&m2);
	for(int i=1;i<=m1;i++)
	{
		p t;
		scanf("%d%d",&a1[i].s,&a1[i].e);
	}
	for(int i=1;i<=m2;i++)
	{
		p t;
		scanf("%d%d",&a2[i].s,&a2[i].e);
	}
	s.clear();
	for(int i=1;i<=m1;i++)
	{
		s.insert(a1[i]);
	} 
	for(int i=1;i<=n;i++)
	{
		int st=0;int ct=0;
		while(1)//遍历取出 
		{
			set<p>::iterator it;
			it=s.lower_bound((p){st,0});
			if(it==s.end()) break;
			st=it->e;
			s.erase(it);
			ct++;
		}
		ans1[i]=ans1[i-1]+ct;
	}
	s.clear();
	for(int i=1;i<=m2;i++)
	{
		s.insert(a2[i]);
	}
	for(int i=1;i<=n;i++)
	{
		int st=0;int ct=0;
		while(1)//同上 
		{
			set<p>::iterator it;
			it=s.lower_bound((p){st,0});
			if(it==s.end()) break;
			st=it->e;
			s.erase(it);
			ct++;
		 } 
		 ans2[i]=ans2[i-1]+ct;
	}
	int ans=-1;;
	for(int i=0;i<=n;i++)
	{
		ans=max(ans,ans1[i]+ans2[n-i]);
	}
	printf("%d",ans);
}

代码写的不是很秀,大佬别打我
大佬链接
本人第一次写博客,不喜勿喷。有错欢迎指出。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值