Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1087 Accepted Submission(s): 710 Problem Description What a sunny day! Let’s go picnic and have barbecue! Today, all kids in “Sun Flower” kindergarten are prepared to have an excursion. Before kicking off, teacher Liu tells them to stand in a row. Teacher Liu has an important message to announce, but she doesn’t want to tell them directly. She just wants the message to spread among the kids by one telling another. As you know, kids may not retell the message exactly the same as what they was told, so teacher Liu wants to see how many versions of message will come out at last. With the result, she can evaluate the communication skills of those kids.
Input The first line contains an integer T indicating the number of test cases, and then T test cases follows.
Output For each test case, print “Case t:” at first ( t is the case No. starting from 1 ). Then print N lines. The ith line contains two integers which indicate the position of the ith (i starts form 1 ) kid’s “left messenger” and “right messenger”. If a kid has no “left messenger” or “right messenger”, print ‘0’ instead. (The position of the leftmost kid is 1, and the position of the rightmost kid is N)
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
Source 2010 National Programming Invitational Contest Host by ZSTU
Recommend wxl | We have carefully selected several similar problems for you: 3405 3406 3407 3408 3411 |
题目大意:现在给你N个数,问你某个数的比他小的数中的最大的数的左右位置。没有的话输出0
思路:这个题目基本上就是单调递减栈用两次,
当比栈顶还低/空栈时表示没符合条件的人,输出0并入栈;
当高于栈顶时,一直pop找到符合条件的最高者记下id即可,记得把这个人最后入栈,
有个地方是把某个高值将他前面的低值都pop掉,用此表示高值挡住前面的低的,虽然是低值但是前面有高值挡住
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<stack>
#define ll long long
using namespace std;
const int maxn=50010;
ll l[maxn],r[maxn];
ll a[maxn];
stack<int >S;
int main()
{
int t,kase=1;scanf("%d",&t);
while(t--)
{
int n;scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
a[n+1]=-1;
while(!S.empty()) S.pop();
for(int i=1;i<=n;i++) //
{
int num=-1,pos;
while(!S.empty()&&a[S.top()]<a[i])
{
if(a[S.top()]>num)
{
num=a[S.top()];
pos=S.top();
}
S.pop();
}
if(num==-1) l[i]=0;
else l[i]=pos;
S.push(i);
}
while(!S.empty())S.pop();
for(int i=n;i>=1;i--)
{
int num=-1,pos;
while(!S.empty()&&a[S.top()]<a[i])
{
if(a[S.top()]>num)
{
num=a[S.top()];
pos=S.top();
}
S.pop();
}
if(num==-1) r[i]=0;
else r[i]=pos;
S.push(i);
}
printf("Case %d:\n",kase++);
for(int i=1; i<=n; i++)
{
printf("%lld %lld\n",l[i],r[i]);
}
}
}