1272 最大距离
- 1 秒
- 131,072 KB
- 20 分
- 3 级题
给出一个长度为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。
收起
输入
第1行:1个数N,表示数组的长度(2 <= N <= 50000)。 第2 - N + 1行:每行1个数,对应数组元素Ai(1 <= Ai <= 10^9)。
输出
输出最大距离。
输入样例
6 5 3 6 3 4 2
输出样例
3
题解:思路一:用结构体封装起 值和位置,按值排序(值相同时,按“位置”排序),遍历一遍,当“位置”大于之前的“位置”, 意味着距离可以更新。
#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<bitset>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define eps (1e-8)
#define MAX 0x3f3f3f3f
#define u_max 1844674407370955161
#define l_max 9223372036854775807
#define i_max 2147483647
#define re register
#define pushup() tree[rt]=max(tree[rt<<1],tree[rt<<1|1])
#define nth(k,n) nth_element(a,a+k,a+n); // 将 第K大的放在k位
#define ko() for(int i=2;i<=n;i++) s=(s+k)%i // 约瑟夫
using namespace std;
inline int read(){
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
typedef long long ll;
const double pi = atan(1.)*4.;
const int M=1e3+5;
const int N=1e5+5;
struct fun{
int a,id;
}f[N];
bool cmp(fun x,fun y){
if(x.a==y.a)
return x.id<y.id;
else
return x.a<y.a;
}
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&f[i].a),f[i].id=i;
sort(f,f+n,cmp);
int tem=f[0].id,ans=0; // ans 存放最远距离
for(int i=1;i<n;i++){
if(tem>f[i].id) tem=f[i].id;
else ans=max(ans,f[i].id-tem); // 更新
}
printf("%d\n",ans);
return 0;
}
思路二:线段树+二分区间,区间只需要统计最大值
#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<bitset>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define eps (1e-8)
#define MAX 0x3f3f3f3f
#define u_max 1844674407370955161
#define l_max 9223372036854775807
#define i_max 2147483647
#define re register
#define pushup() tree[rt]=max(tree[rt<<1],tree[rt<<1|1])
#define nth(k,n) nth_element(a,a+k,a+n); // 将 第K大的放在k位
#define ko() for(int i=2;i<=n;i++) s=(s+k)%i // 约瑟夫
using namespace std;
inline int read(){
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
typedef long long ll;
const double pi = atan(1.)*4.;
const int M=1e3+5;
const int N=1e5+5;
int n;
int tree[N<<2],a[N];
void sett(int l,int r,int rt){
if(l==r){
tree[rt]=a[l];
return ;
}
int mid=l+r>>1;
sett(l,mid,rt<<1);
sett(mid+1,r,rt<<1|1);
pushup();
}
int findd(int a,int b,int l,int r,int rt){
if(a<=l&&b>=r)
return tree[rt];
int ans=0;
int mid=l+r>>1;
if(a<=mid)
ans=max(ans,findd(a,b,l,mid,rt<<1));
if(b>mid)
ans=max(ans,findd(a,b,mid+1,r,rt<<1|1));
return ans;
}
bool J(int x,int mid){
int d=findd(mid,n,1,n,1);
if(d>=x) return true;
else return false;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
sett(1,n,1);
int ans=0;
for(int i=1;i<n;i++){
int l=i,r=n;
while(r-1>l){
int mid=l+r>>1;
if(J(a[i],mid)) l=mid;
else r=mid;
}
if(J(a[i],r)) ans=max(ans,r-i);
else ans=max(ans,l-i);
}
printf("%d\n",ans);
return 0;
}