hdu 3410 单调栈

Description

现在有n个人站成一行,告诉你每个人的身高。
现在每个人都要找到在他左边,比他矮的人中最高的人的位置。
同时也要找到,在他右边比他矮的人中最高的人的位置。
注意由于他们是站成一行的,所以他们不能越过比他们高的人去看后面的人。也就是说,他只能看到他本人和他的左边(或右边)第一个比他高的人之间的那些人。
请输出每个人左边比他矮的人中最高的人的位置,以及每个人的右边比他矮的人中最高的人的位置(没有的话输出0,位置从1开始)

Input

第一行输入一个整数T,表示有T组数据。

每一组数据包含两行,第一行输入一个整数n(0 < n <= 50000),表示有n个人。第二行有n个整数,表示所有人的身高。

数据保证每个人的身高都是不同的,而且身高小于2^31。

Output

对于每组数据,输出“Case t:” ( t 表示是第几组数据的答案, t从1开始,双引号不算 )。

然后输出n行,第i行包含两个整数,表示第i个人的左边符合条件的人的位置和右边符合条件的人的位置。如果没有输出0,有就输出位置(位置从1开始)

Sample Input

2
5
5 2 4 3 1
5
2 1 4 3 5

Sample Output

Case 1:
0 3
0 0
2 4
0 5
0 0
Case 2:
0 2
0 0
1 4
0 0

3 0

思路:维护一个单减栈,如果当前要进栈的元素小于栈顶则直接进栈说明当前它最小则不能延伸,赋值为0,如果当前进栈的元素大于栈顶就一直POP直到可以入栈,就找到了左右比他矮的中最大的;

#include #include #include #define N 50010 using namespace std; int a[N]; int l[N]; int r[N]; int main() {     int t,i;       int k=1;      scanf("%d",&t);       while(t--)       {  memset(l,0,sizeof(l));          memset(r,0,sizeof(r));          stackst,q;     while(!st.empty())      st.pop();      int n;     scanf("%d",&n);            for(i=1;i<=n;i++)  {      scanf("%d",&a[i]);              if(st.empty())              { l[i]=0;                st.push(i); } else { if(a[st.top()] while(st.empty()==0&&a[st.top()] {        l[i]=st.top();          st.pop(); }  st.push(i);     }    else      {      l[i]=0;              st.push(i);  }  }     }     //while(!st.empty())     //st.pop();     for(i=n;i>=1;i--)     {   if(q.empty())          { r[i]=0;            q.push(i);  }     else  {      if(a[q.top()]         {   while(q.empty()==0&&a[q.top()]             {   r[i]=q.top();                 q.pop(); } q.push(i); } else { r[i]=0;   q.push(i); }    } } printf("Case %d:\n",k++); for(i=1;i<=n;i++) printf("%d %d\n",l[i],r[i]);  }  return 0; }

你可能感兴趣的:(hdu,基础题,单调栈)