D

题目链接:https://cn.vjudge.net/problem/Gym-100971D

题目大意:给你n个城市的信息,每一个城市的信息包括坐标和人数,然后让你找每一个城市的父亲,作为一个城市的父亲具体满足的条件是:作为父亲的城市的坐标和当前城市的人数最多,,如果有多个满足的城市,则和原来的点相隔最近的作为父亲。

具体思路:首先,题目中说坐标和人数是不会有相同的值,所以我们对于每一个点,按照x轴进行排序之后,找出当前点的左边的第一个人数大于当前点的,然后再找出当前点的右边的第一个人数大于当前点的,这个过程可以通过单调栈来维护,然后再具体找的过程中,先看当前的这个点的左边和右边时候都存在,如果都没有,就证明没有父亲,如果有一个,这个点就是父亲,如果都有的话,就是寻找相隔最近的就可以了。

AC代码:

 1 #include<iostream>
 2 #include<stack>
 3 #include<cmath>
 4 #include<stdio.h>
 5 #include<algorithm>
 6 #include<stack>
 7 #include<string>
 8 using namespace std;
 9 # define ll long long
10 const int maxn = 2e5+100;
11 int L[maxn],R[maxn];
12 int val[maxn],x[maxn];
13 int pos[maxn],ans[maxn];
14 bool cmp(int t1,int t2){
15 return x[t1]<x[t2];
16 }
17 int main(){
18 int n;
19 scanf("%d",&n);
20 for(int i=1;i<=n;i++){
21 scanf("%d %d",&x[i],&val[i]);
22 pos[i]=i;
23 }
24 sort(pos+1,pos+n+1,cmp);
25 stack<int>q;
26 for(int i=1;i<=n;i++){
27 if(!q.empty())L[pos[i]]=-1;
28 while(!q.empty()&&val[q.top()]<=val[pos[i]])q.pop();
29 if(q.empty())L[pos[i]]=-1;
30 else L[pos[i]]=q.top();
31 q.push(pos[i]);
32 }
33 while(!q.empty())q.pop();
34 for(int i=n;i>=1;i--){
35 if(!q.empty())R[pos[i]]=-1;
36 while(!q.empty()&&val[q.top()]<=val[pos[i]])q.pop();
37 if(q.empty())R[pos[i]]=-1;
38 else R[pos[i]]=q.top();
39 q.push(pos[i]);
40 }
41 for(int i=1;i<=n;i++){
42 if(L[i]==-1&&R[i]==-1)ans[i]=-1;
43     else if(L[i]==-1)ans[i]=R[i];
44     else if(R[i]==-1)ans[i]=L[i];
45     else {
46     if(abs(x[R[i]]-x[i])>abs(x[L[i]]-x[i]))ans[i]=L[i];
47     else if(abs(x[R[i]]-x[i])<abs(x[L[i]]-x[i]))ans[i]=R[i];
48     else {
49     if(val[R[i]]>val[L[i]])ans[i]=R[i];
50     else ans[i]=L[i];
51     }
52     }
53 }
54 for(int i=1;i<=n;i++){
55 if(i==1)printf("%d",ans[i]);
56 else printf(" %d",ans[i]);
57 }
58 printf("
");
59 return 0;
60 }
原文地址:https://www.cnblogs.com/letlifestop/p/10386794.html