Description
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 03 0
思路:维护一个单减栈,如果当前要进栈的元素小于栈顶则直接进栈说明当前它最小则不能延伸,赋值为0,如果当前进栈的元素大于栈顶就一直POP直到可以入栈,就找到了左右比他矮的中最大的;
#include<stdio.h> #include<stack> #include<string.h> #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)); stack<int>st,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()]<a[i]){ while(st.empty()==0&&a[st.top()]<a[i]) { 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()]<a[i]) { while(q.empty()==0&&a[q.top()]<a[i]) { 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; }