1409E. Two Platforms(枚举,二分)

E. Two Platforms

这题还是有一些细节的…

题意:

有两块长k的板子,可以在任意整数座标水平放置,问最多有多少小球的投影在板子上

首先注意到所有小球只关系它的 x x 座标,与 y y 座标无关

因为同样的 x x 座标,板子的 y y 座标肯定无穷小(能接住所有掉下来的小球)

所以现在问题是两段长k的线段,最多能覆盖多少点?

所以现在问题就不难了

x 先对小球x座标排个序

i 然后枚举第一块木板从第i个小球开始覆盖

j 用二分查找出最多能覆盖到第j个小球

j + 1 ? ? 那么第二块木板是从j+1个小球开始覆盖最优吗??

, j + 2 , j + 3 . . . . 当然不是,可以从j+2开始覆盖,可以从j+3开始覆盖....

h o u [ i ] , [ i , n ] 所以预处理一个hou[i]数组,表示从第[i,n]个小球开始覆盖的最优取值

, 这样就可以枚举第一块板子快速得到第二块板子的最优秀值,细节看代码吧

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=2e5+10;
int a[maxn],b[maxn],c[maxn],pre[maxn];
bool com( int a,int b){
	return a<b;
}
int qian[maxn],hou[maxn];
signed main()
{
	int t,n,k;
	cin >> t;
	while( t-- )
	{
		cin >> n >> k;
		for(int i=1;i<=n;i++)	cin >> a[i];
		for(int i=1;i<=n;i++)	cin >> b[i];
		sort(a+1,a+1+n,com);
		for(int i=n;i>=1;i--)
		{
			int nowx=a[i]+k;//从第i个小球开始覆盖,最远可以覆盖到nowx
			int index=upper_bound(a+1,a+1+n,nowx)-a;//刚好大于nowx的索引 
			hou[i]=max( hou[i+1],index-i );//取max,因为数组hou[i]的含义是从[i,n]任选一个小球开始覆盖的最优值 
		}
		int ans=0;
		for(int i=1;i<=n;i++)//枚举第一块木板从i位置开始覆盖 
		{
			int nowx=a[i]+k;
			int index=upper_bound(a+1,a+1+n,nowx)-a;//刚好大于nowx的索引 
			ans=max( ans,hou[index]+(index-i) );
		}
		cout << ans << endl;
		for(int i=0;i<=n+1;i++)	hou[i]=0;
	}
}

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/108417444