D - Laying Cables Gym - 100971D (单调栈)
题目链接: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("\n"); 59 return 0; 60 }