C. Min-Max Array Transformation(二分/贪心)

题目

题意

给定长度为n的非递减数组a,1<=a[i]<=1e9, a[i]<=a[i+1]
定义数组b,b[i]=a[i]+d[i], 0<=d[i]

现给定数组a,b。

求d数组在每个位置能取到的最大、最小值。
每个位置的最大值、最小值,不同位置的最大值、最小值都是相互独立的,即它们可以对应不同的d数组。

题目输入保证有解。即至少存在一组d,使得b[i]=a[i]+d[i], 0<=d[i]

思路

对于最小值,则直接取b数组中第一个大于等于a[i]的即可。

对于最大值,考虑取尽量最大的。要保证i+1,i+2,…,n这些位置都已经用最小的b元素填充了。

详见代码。

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 200010;

int n, m;
int a[maxn], b[maxn];
int mn[maxn], mx[maxn];

void solve() {
	scanf("%d", &n);
	for (int i = 0; i < n; ++i) {
		scanf("%d", &a[i]);
	}
	for (int i = 0; i < n; ++i) {
		scanf("%d", &b[i]);
	}
	
	// 直接取b数组中第一个大于等于a[i]的即可。
	for (int i = 0; i < n; ++i) {
		int pos = lower_bound(b, b + n, a[i]) - b;
		mn[i] = b[pos] - a[i];
	}
	
	// 求最大值 
	multiset<int> st(b, b + n);
	for (int i = n - 1; i >= 0; --i) {
		// 取当前最大值 
		mx[i] = *(--st.end()) - a[i]; 
		// 求i-1的最大值,要先去掉 i, ..., n的最小适配的b元素 
		st.erase(st.lower_bound(a[i]));
	}
	
	for (int i = 0; i < n - 1; ++i) {
		printf("%d ", mn[i]);
	}
	printf("%d\n", mn[n-1]);
	for (int i = 0; i < n - 1; ++i) {
		printf("%d ", mx[i]);
	}
	printf("%d\n", mx[n-1]);
}
int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		solve();
	}
}

最后

觉得文章不错子,可以weixin 搜索 对方正在debug,文章会首发到gongzhonghao上,一起快乐刷题吧~

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值