传递信息
内存限制: 256 MiB 时间限制: 1000 ms 标准输入输出 题目类型: 传统 评测方式: 文本比较
题目描述
现在有n个人站成一行,告诉你每个人的身高。
现在每个人都要找到在他左边,比他矮的人中最高的人的位置。
同时也要找到,在他右边比他矮的人中最高的人的位置。
注意由于他们是站成一行的,所以他们不能越过比他们高的人去看后面的人。也就是说,他只能看到他本人和他的左边(或右边)第一个比他高的人之间的那些人。
请输出每个人左边比他矮的人中最高的人的位置,以及每个人的右边比他矮的人中最高的人的位置(没有的话输出0,位置从1开始)
输入格式
第一行输入一个整数T,表示有T组数据。
每一组数据包含两行,第一行输入一个整数n(0 < n <= 50000),表示有n个人。第二行有n个整数,表示所有人的身高。
数据保证每个人的身高都是不同的,而且身高小于2^31。
输出格式
对于每组数据,输出“Case t:” ( t 表示是第几组数据的答案, t从1开始,双引号不算 )。
然后输出n行,第i行包含两个整数,表示第i个人的左边符合条件的人的位置和右边符合条件的人的位置。如果没有输出0,有就输出位置(位置从1开始)
样例
样例输入
复制2
5
5 2 4 3 1
5
2 1 4 3 5
样例输出
复制Case 1:
0 3
0 0
2 4
0 5
0 0
Case 2:
0 2
0 0
1 4
0 0
3 0
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e4 + 5;
int n, x;
int a[maxn];
int main() {
scanf("%d", &x);
for(int i = 1; i <= x; i++) {
scanf("%d", &n);
for(int j = 1; j <= n; j++) {
scanf("%d", &a[j]);
}
printf("Case %d:\n", i);
for(int j = 1; j <= n; j++) {
int Max = 0, t = 0;
for(int k = j - 1; k >= 1; k--) {
if(a[k] > a[j]) {
break;
} else if(a[k] > Max) {
t = k;
Max = a[k];
}
}
printf("%d ", t);
Max = 0, t = 0;
for(int k = j + 1; k <= n; k++) {
if(a[k] > a[j]) {
break;
} else if(a[k] > Max) {
t = k;
Max = a[k];
}
}
printf("%d\n", t);
}
}
return 0;
}
这篇暴枚测出时间 500ms 以内,1000ms是可以过的,But要是你对自己要求更高,时间更短,就会用单调栈:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e4 + 5;
int n, t;
int a[maxn], l[maxn], r[maxn];
stack<int> s;
int main() {
scanf("%d", &t);
for(int i = 1; i <= t; i++) {
for(int j = 1; j < maxn; j++) {
l[j] = 0;
r[j] = 0;
}
while(!s.empty()) {
s.pop();
}
scanf("%d", &n);
for(int j = 1; j <= n; j++) {
scanf("%d", &a[j]);
}
printf("Case %d:\n", i);
for(int j = 1; j <= n; j++) {
while(!s.empty() && a[j] > a[s.top()]) {
l[j] = s.top();
s.pop();
}
s.push(j);
}
while(!s.empty()) {
s.pop();
}
for(int j = n; j >= 1; j--) {
while(!s.empty() && a[j] > a[s.top()]) {
r[j] = s.top();
s.pop();
}
s.push(j);
}
for(int j = 1; j <= n; j++) {
printf("%d %d\n", l[j], r[j]);
}
}
return 0;
}