【51Nod - 1272 】最大距离 (思维,排序sort的空间优化)

版权声明:欢迎学习我的博客,希望ACM的发展越来越好~ https://blog.csdn.net/qq_41289920/article/details/83099502

题干:

给出一个长度为N的整数数组A,对于每一个数组元素,如果他后面存在大于等于该元素的数,则这两个数可以组成一对。每个元素和自己也可以组成一对。例如:{5, 3, 6, 3, 4, 2},可以组成11对,如下(数字为下标):

(0,0), (0, 2), (1, 1), (1, 2), (1, 3), (1, 4), (2, 2), (3, 3), (3, 4), (4, 4), (5, 5)。其中(1, 4)是距离最大的一对,距离为3。

Input

第1行:1个数N,表示数组的长度(2 <= N <= 50000)。 
第2 - N + 1行:每行1个数,对应数组元素Ai(1 <= Ai <= 10^9)。

Output

输出最大距离。

Sample Input

6
5
3
6
3
4
2

Sample Output

3

解题报告:

   这题第一反应是线段树,,但是想想思维题怎么可能上数据结构呢?所以开始往思维方面想,无非就是结构体存位置,排序,开一个数组存某个数最早(或晚)出现的位置等等方法呗、、、 

   线段树也不难想,离散化一下之后从头到尾扫,在离散化后的值那个权值那里存一下下标,并标记说这个值已经出现过了,即维护每个数字出现的最早时刻,即最小下标,然后扫到下一个数a[i]查询1~getpos(a[i])查询区间最小值,维护差的最大值就可以了。getpos是找到a[i]对应的离散化以后的值。

   这题我还想到了可否用set<pair>去维护,在线更新set,这样满足了每次查找的元素出现的先后关系,但是对于值的大小,emmm,不好搞啊。反正51Nod - 1065这题是可以set做的。

   这题看看代码就懂了,题目中有两个要素,元素的先后出现的关系,关系是大于等于。排序的目的就是为了先满足后者(因为后者最麻烦所以先让他满足)(为啥最麻烦呢?因为看前后的话比较一下pos然后维护最小值就可以了,但是对于值的话,无法满足这个单调性,也就是,不好满足前缀可维护关系,所以我们先排序,排除了这个因素,剩下的就是维护一个pos最小值了。)

AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,ans;
struct Node {
	int val,pos;
} node[50000 + 5];
bool cmp(const Node& a,const Node& b) {
	if(a.val!= b.val) return a.val < b.val;
	return a.pos < b.pos;
}
int main() 
{
	cin>>n;
	for(int i = 1; i<=n; i++) {
		scanf("%d",&node[i].val);node[i].pos = i;
	}
	sort(node+1,node+n+1,cmp);
	int curpos = node[1].pos;
	for(int i = 1; i<=n; i++) {
		curpos = min(curpos,node[i].pos);
		ans = max(ans,node[i].pos - curpos); 
	}
	printf("%d\n",ans);
	return 0 ;
}

另:如果要求了空间复杂度,那么就不能排序解决了,这时候考虑用优先队列去优化空间。 (很巧妙但是可能只有面试的时候会遇到对空间有特别的要求的)

AC代码2:(空间复杂度o(1)的版本)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct Node {
	int val,pos;
	friend bool operator <(Node x,Node y) {
		if(x.val==y.val) return x.pos>y.pos;
		return x.val>y.val;
	}
};
priority_queue<Node> pq;
int n;
int main() {
	cin>>n;
	Node tmp;
	for(int i = 1; i<=n; i++) {
		scanf("%d",&tmp.val);tmp.pos=i;
		pq.push(tmp);
	}
	int cur=n,ans=0;
	while(!pq.empty()) {
		Node now = pq.top();pq.pop();
		if(now.pos<cur)  cur=now.pos;
		ans=max(ans,now.pos-cur);
		
	}
	printf("%d\n",ans);

	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41289920/article/details/83099502
今日推荐