这道题我本来在一个半小时前就可以解决的,但有测试点超时了,我想用二分查找(在“1”处)这样应该就可以过了,但就这一个二分查找,我写了很久。由于本人过于弱,不是这个不行就是那个不会,那么久也写不出来。
如果可以,就请帮我优化一下代码吧。
题目:P7913 [CSP-S 2021] 廊桥分配
测试点:
代码:
#include <bits/stdc++.h>
using namespace std;
int n,m1,m2;
int num;
struct zong1
{
int a,b;
}g[100005];//记录国内飞机停靠。
struct zong2
{
int aj,bj;
}j[100005];//记录国外飞机停靠。
int ji1[100005],ji2[100005];
//分别统计国内外用廊桥i的数量 。
bool cmp(zong1 a1,zong1 a2){
return (a1.a<a2.a);
}
bool cmp2(zong2 a1,zong2 a2){
return (a1.aj<a2.aj);
}//排序要求。
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
//输入数据。
cin>>n>>m1>>m2;
for (int i=1;i<=m1;i++)
cin>>g[i].a>>g[i].b;
for (int i=1;i<=m2;i++)
cin>>j[i].aj>>j[i].bj;
//排序
sort(g+1,g+1+m1,cmp);
sort(j+1,j+1+m2,cmp2);
//分配国内航班停靠的廊桥。
int lin=1,last[100005];
num=0;
for (int i=1;i<=m1;i++)
{
num++;
for (int j=1;j<=num;j++)
if (g[i].a>=last[j])
{
lin=j;
break;
}
if (num>lin)
num--;
ji1[lin]++;
last[lin]=g[i].b;
}
//分配国外航班停靠的廊桥
lin=1,num=0;//初始化。
memset(last,0,sizeof(last));
for (int i=1;i<=m2;i++)
{
num++;
for (int j1=1;j1<=num;j1++)
if (j[i].aj>=last[j1])
{
lin=j1;
break;
}
if (num!=lin)
num--;
ji2[lin]++;
last[lin]=j[i].bj;
}
//计算(国内外航班停靠廊桥的)前缀和。
int sum1[100005],sum2[100005];
sum1[0]=0,sum2[0]=0;
for (int i=1;i<=n;i++)
sum1[i]=sum1[i-1]+ji1[i];
for (int i=1;i<=n;i++)
sum2[i]=sum2[i-1]+ji2[i];
//求解。
int ans=0;
for (int i=0;i<=n;i++){//枚举国内廊桥数。
int i2=n-i;//国外廊桥数。
ans=max(sum1[i]+sum2[i2],ans);//求最大值。
}
cout<<ans<<"\n";
return 0;
}