Codeforces Round #484 (Div. 2) D. Shark(STL)982D

D. Shark
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

For long time scientists study the behavior of sharks. Sharks, as many other species, alternate short movements in a certain location and long movements between locations.

Max is a young biologist. For nn days he watched a specific shark, and now he knows the distance the shark traveled in each of the days. All the distances are distinct. Max wants to know now how many locations the shark visited. He assumed there is such an integer kk that if the shark in some day traveled the distance strictly less than kk, then it didn't change the location; otherwise, if in one day the shark traveled the distance greater than or equal to kk; then it was changing a location in that day. Note that it is possible that the shark changed a location for several consecutive days, in each of them the shark traveled the distance at least kk.

The shark never returned to the same location after it has moved from it. Thus, in the sequence of nn days we can find consecutive nonempty segments when the shark traveled the distance less than kk in each of the days: each such segment corresponds to one location. Max wants to choose such kk that the lengths of all such segments are equal.

Find such integer kk, that the number of locations is as large as possible. If there are several such kk, print the smallest one.

Input

The first line contains a single integer nn (1n1051≤n≤105) — the number of days.

The second line contains nn distinct positive integers a1,a2,,ana1,a2,…,an (1ai1091≤ai≤109) — the distance traveled in each of the day.

Output

Print a single integer kk, such that

  1. the shark was in each location the same number of days,
  2. the number of locations is maximum possible satisfying the first condition,
  3. kk is smallest possible satisfying the first and second conditions.
Examples
input
Copy
8
1 2 7 3 4 8 5 6
output
Copy
7
input
Copy
6
25 1 2 3 14 36
output
Copy
2
Note

In the first example the shark travels inside a location on days 11 and 22 (first location), then on 44-th and 55-th days (second location), then on 77-th and 88-th days (third location). There are three locations in total.

In the second example the shark only moves inside a location on the 22-nd day, so there is only one location.

一、原题地址

    传送门

二、大致题意

    有一群鲨鱼,在n天里在一片海域游动。给出n天里鲨鱼的游动距离。现在有一个k值,当某天鲨鱼游动的距离大于等于k时,鲨鱼前往下一片海域。现在询问的是最小的一个k,保证鲨鱼游动的海域数最多。

    从数据上看就是,给出n个数,删掉其中大于等于k的数,然后要求还能连续的片段是最多的,在保证最多的基础上求k的最小值。

三、思路

    看了大佬们的代码思路清晰。

    我们在给出的n天里面从大到小枚举当前应该删除的数。此时我们可以将n天看作是一长段,每次执行删除操作的时候就是把一个长段变为两个小段。

    所以对于当前应该删除的数,我们找到它在当前段上所在的位置记作pos。然后找出它所在的应该分成两份的段,记这个段的头为head,尾为tail。

    那么这一长段的大小就是tail-head-1。

    分成的小段分别为pos-head-1和tail-pos-1。

    开一个map记录map[i]=j,表示长度为i的段个数为j。

    那么当map的size为1时就是所有段的大小相等的时候,此时更新我们的答案。若当前应该删除的是x,那么答案应该是在n天里比x小的数(y)+1。

四、代码

    

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
using namespace std;
const int inf = 0x3f3f3f3f;
long long  gcd(long long  a, long long  b) { return a == 0 ? b : gcd(b % a, a); }


set<pair<int,int>>s;		//记录n天里鲨鱼游动的距离
set<int>ts;					//模拟分割成段的过程
map<int, int>mmp;			//map[i]=j,表示长度为i的段个数为j。
int main()
{
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		int x;
		scanf("%d", &x);
		s.insert(make_pair(x, i));		//第i天距离为x
	}
	ts.insert(0);
	ts.insert(n+1);
	mmp[n]=1;
	int ans = s.rbegin()->first + 1;
	int cnt = 1;
	for (int i = 0; i < n - 1; i++)
	{
		auto it = s.rbegin();				//取距离最大的某天
		int pos = it->second;				//当前对应的某天记作pos
		s.erase(*it);	//已操作过
		int head, tail;
		head = *(--ts.lower_bound(pos));	//找出pos所在段的头
		tail = *(ts.upper_bound(pos));		//找出pos所在段的尾

		ts.insert(pos);						//插入pos,将这一段分割
		mmp[tail - head - 1]--;				//分割后这么长一段的就消失了
		if (mmp[tail - head - 1] == 0)
		{
			mmp.erase(tail - head - 1);
		}
		mmp[pos - head - 1]++;				//分割后将出现的两个小段
		mmp[tail - pos - 1]++;				//分割后将出现的两个小段
		mmp.erase(0);
		if (mmp.size() == 1)				//若只有一种长度大小
		{
			int now = mmp.begin()->second;
			if (now >= cnt) 
			{
				cnt = now;
				ans = s.rbegin()->first + 1;
			}
		}
	}
	cout << ans << endl;
	getchar();
	getchar();
}

猜你喜欢

转载自blog.csdn.net/amovement/article/details/80386962