题目来源
题目描述:
Seg-El has last chance to make the final changes in order to prevent the destruction of Krypton.
He is provided an array Arr[ ] of N elements.
For each element Arr [ i ], he needs to find the largest element Arr [ j ] where j < i and Arr [ j ] < Arr [ i ]
Help him to achieve this task.
输入描述:
First line comprises N- the number of elements in the array.
Second line contains N space separated integers denoting the elements of the array.
输出描述:
Print N lines denoting the required answer as specified above. In case no such value exists for some
Arr [ i ], print "-1" (without quotes).
Constraints:
- 1 ≤ N ≤ 200000
- 1 ≤ Arr [ i ] ≤ 10的15次方
Example
5
1 2 3 5 4
Output:
-1
1
2
3
3
题目分析:简单解释一下题目意思,第一行输入一个N,第二行依此输入N个数。需要我们做的是将每个数前面最大且比该数小的数输出,简单点说就是输出小的里面最大的那个数,如果不存在,输出-1。本题应该想到插入排序,输入一个数时使用二分查找到一个属于他的位置让他插入,同时输出他前面一个比他小的数。使用这种插入方法如果用数组的话每插入一个数后面的数都要往后移一位,肯定会超时,所以我们使用set,set中的排序刚好就是我所说的这种,而且set没有重复的元素,我们找时只需要找他前面一位即可。
不使用函数代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <set>
using namespace std;
long long a[200055];
int main()
{
set<long long> sets;
long long flag;
int n,i;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%lld",&a[i]);
for(i=0;i<n;i++)
{
flag=-1;//初始化为-1,如果flag没有被改变的话直接输出-1.
if(i>0)
{
sets.insert(a[i]);
set<long long>::iterator index=sets.find(a[i]);//找到该元素插入的位置
if(index!=sets.begin())//如果位置不为第一个的话说明前一个比它小因为无重复元素
{
index--;
flag=*index;//index代表位置*index代表该位置的数
}
printf("%lld\n",flag);
}
else
{
sets.insert(a[i]);
printf("-1\n");
}
}
return 0;
}
使用函数(upper_bound())代码:
#include <iostream>
#include <stdio.h>
#include <set>
#include <stdio.h>
using namespace std;
long long a[200010];
int main()
{
set<long long> sets;
int n,i,flag=0;
scanf("%d",&n);
for(i=0; i<n; i++)
scanf("%lld",&a[i]);
set<long long>::iterator index;
for(i=0; i<n; i++)
{
sets.insert(-a[i]);//将a数组取反插入,为upper_bound函数做准备。
index=sets.upper_bound(-a[i]);//upper_bound函数返回第一个大于该数的元素位置,现在知道为什么要取反插入了吧
if(index!=sets.end()) //如果bu等于最后一个元素的后一个位置说明存在这样一个数
cout<<-*index<<endl;
else
printf("-1\n");
}
return 0;
}