题意:

给你两个数组,长度为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;
}