AT_abc302_d

题意

一个人要送礼物给另外两个人,现有 \(n\) 件礼物要选一件送给第一个人,价值分别为 \(a_1,a_2,\cdots,a_n\),有 \(m\) 件礼物要选一件送给第二个人,价值分别为 \(b_1,b_2,\cdots,b_m\)。求在两件礼物之差不超过 \(d\) 的情况下,价值总和的最大值。

思路

首先不难想到,要将 \(a\)\(b\) 分别排序。然后对于每个 \(a_i\)\(b_i\) 做法同理),在 \(b\) 中二分查找 $ a_i - d $ 和 $ a_i + d $ 的位置,如果前者的位置大于后者,则说明矛盾,排去,否则计算此时的价值,并且更新答案(如果价值更大)。

具体实现见代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#define int long long

using namespace std;
int k1,k2,n,m,d,a[1000001],b[1000001],ans = -1 ;

signed main()
{
	cin >> n >> m >> d;
	for( int i = 1 ; i <= n ; i ++ )
		cin >> a[i];
	for( int i = 1 ; i <= m ; i ++ )
		cin >> b[i];
	sort( a + 1 , a + n + 1 );
	sort( b + 1 , b + m + 1 );
	for( int i = 1 ; i <= n ; i ++ )
	{
		k1 = a[i] - d;
		k2 = a[i] + d;
		k1 = lower_bound( b + 1 , b + m + 1 , k1 ) - b;
		k2 = upper_bound( b + 1 , b + m + 1 , k2 ) - b;
		k2 --;
		if( k1 > k2 ) continue;
		k2 = min( k2 , m );
		ans = max( ans , a[i] + b[k2] );
	}
	for( int i = 1 ; i <= m ; i ++ )
	{
		k1 = b[i] - d;
		k2 = b[i] + d;
		k1 = lower_bound( a + 1 , a + n + 1 , k1 ) - a;
		k2 = upper_bound( a + 1 , a + n + 1 , k2 ) - a;
		k2 --;
		if( k1 > k2 ) continue;
		k2 = min( k2 , n );
		ans = max( ans , b[i] + a[k2] );
	}
	cout << ans;
	return 0;
}
posted @ 2024-01-20 18:07  liyilang2021  阅读(10)  评论(0编辑  收藏  举报