Find my Family
You are looking for a particular family photo with you and your favorite relatives Alice and Bob. Each family photo contains a line-up of n people. On the photo you’re looking for, you remember that Alice, who is taller than you, was somewhere on your left from the perspective of the photographer. Also, Bob who is taller than both you and Alice, was standing somewhere on your right. Since you have a large number of family photos, you want to use your computer to assist in finding the photo. Many of the photos are quite blurry, so facial recognition has proven ineffective. Luckily, the Batch Apex Photo Classifier, which detects each person in a photo and outputs the sequence of their (distinct) heights in pixels, has produced excellent results. Giventhissequenceofheightsfor k photos, determinewhichofthesephotoscouldpotentially be the photo you’re looking for.
Input • The first line contains 1≤ k ≤1000, the number of photos you have to process. • Then follow two lines for each photo. – The first line contains a single integer 3 ≤ n ≤ 3·105, the number of people on this photo. – The second line contains n distinct integers 1 ≤ h1,…,hn ≤ 109, the heights of the people in the photo, from left to right.
It is guaranteed that the total number of people in all photos is at most 3·105. Output
• On the first line, output the number of photos k that need further investigation. • Then print k lines each containing a single integer 1≤ ai ≤ n, the sorted indices of the photos you need to look at.
Sample Input
1 3 2 1 3
Sample Output
1 1
Sample Input
4 4 140 157 160 193 5 15 24 38 9 30 6 36 12 24 29 23 15 6 170 230 320 180 250 210
Sample Output
2 2 4
官方题解
题目意思很直白,找出存在中间的数比左边的数小,右边的数比左边的数大,如果对于暴力求法,在 n 次情况下必定超时,此时就需要两个客观意义上的指针。首先解决右边的数,那么我们把第 i 个数以后 最大的数找出,就可以解决右边数的最大值,剩下的就是左边的数,我们可以同过 set 和二分来查找出 比当前 数恰好大一点的数, 若有,再用此数 和右边的最大数相比即可。这样最后的时间复杂度是 O(nlogn)。
个人收获: 没有什么是多加一个数组解决不了的, 如果有, 就再加一个
感觉存右边最大数的地方比较巧妙, max_h[i] = maxh
如果当前值小于该值, 则可判断此后仍有大于当前值的值, 即照片可能符合要求
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <queue>
#include <vector>
using namespace std;
const int N = 300006;
const int inf = 0x3f3f3f3f;
int h[N], max_h[N];
set<int> st;
vector<int> ans;
int main()
{
int k, n, i, j, maxh;
scanf("%d", &k);
int cas = 0;
while(k--)
{
++cas;
scanf("%d", &n);
memset(h, 0, sizeof h);
maxh = 0;
for(i = 0; i < n; ++i)
scanf("%d", &h[i]);
for(i = n-1; i >= 0; --i)
{
if(h[i] > maxh)
maxh = h[i];
max_h[i] = maxh;
}
for(i = 0; i < n; ++i)
{
st.insert(h[i]);
set<int>::iterator pos = st.upper_bound(h[i]);
if(pos != st.end() && *pos < max_h[i])
{
ans.push_back(cas);
break;
}
}
st.clear();
}
printf("%d\n", ans.size());
int cnt = ans.size();
for(i = 0; i < cnt; ++i)
printf("%d\n", ans[i]);
return 0;
}