题意:
给你两个数组,长度为n,让你求出 p, (1 <= p <= n), 在 1~p中 的任意区间, a数组和b数组的最小值下标一样
题目链接:
https://ac.nowcoder.com/acm/contest/881/A
题解:
用单调栈维护数组内的元素单调递减,记录下每个点的左边的比它小的数的所在的位置,如果两点的左边比它小的数的位置不同,那么肯定这一位就不能取了,则输出答案。
AC_code:
#include<bits/stdc++.h>
#define maxn 100005
using namespace std;
int a[maxn], b[maxn], preb[maxn], prea[maxn];
stack<int> s1, s2;
void init() {
while(!s1.empty()) {
s1.pop();
}
while(!s2.empty()) {
s2.pop();
}
}
int main() {
int n;
while(~scanf("%d", &n)) {
init();
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
while(!s1.empty() && a[s1.top()] > a[i]) {
s1.pop();
}
if(s1.empty()) {
prea[i] = 0;
} else {
prea[i] = s1.top();
}
s1.push(i);
}
for(int i = 1; i <= n; i++) {
scanf("%d", &b[i]);
while(!s2.empty() && b[s2.top()] > b[i]) {
s2.pop();
}
if(s2.empty()) {
preb[i] = 0;
} else {
preb[i] = s2.top();
}
s2.push(i);
}
bool f = false;
for(int i = 1; i <= n; i++) {
if(prea[i] != preb[i]) {
f = true;
printf("%d\n", i-1);
break;
}
}
if(!f) {
printf("%d\n", n);
}
}
return 0;
}