P2947 Look Up S
题目描述:
约翰的N(1≤N≤10^5)头奶牛站成一排,奶牛i的身高是Hi(l≤Hi≤1,000,000).现在,每只奶牛都在向右看齐.对于奶牛i,如果奶牛j满足i<j且Hi<Hj,我们可以说奶牛i可以仰望奶牛j. 求出每只奶牛离她最近的仰望对象.
这道题首先我们应该读题后想到达一个暴力来找寻思路,两个for循环就可以把暴力打出来了
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
int a[n+1];
for(int i=1;i<=n;i++){
cin>>a[i];
}
int vis=0;
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
if(a[j]>a[i]){
cout<<j<<endl;
vis=1;
break;
}
}
if(vis!=1){
cout<<"0"<<endl;
}
else{
vis=0;
}
}
cout<<"0"<<endl;
return 0;
}
这样我们就得到了58分(有几个点T掉了)
接下来我们会立马想到对此程序进行优化,加一个
ios::sync_with_stdio(false);语句
将 cin cout 的时间复杂度降到和 scanf printf 相同 然后在吸一下氧气(O2); 这样可以少T一个点了 呀!太棒了
接下来我们就应该想一下正解,单调队列
直接调用STL模板库中的单调队列函数,在单调队列中我们在嵌套一个结构体,储存数字和位置这样就OK了
deque<node>q;
单调队列代码:
#include<bits/stdc++.h>
using namespace std;
int n,f[100010];
struct node{
int sz;
int wz;
}e;
deque<node>q;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
int a;
cin>>a;
while (!q.empty()&&q.back().sz<a){
f[q.back().wz]=i;
q.pop_back();
}
e.sz=a; e.wz=i;
q.push_back(e);
}
for(int i=1;i<=n;i++){
cout<<f[i]<<endl;
}
return 0;
}
浙公网安备 33010602011771号