博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

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;
}

 

posted @ 2020-06-17 11:11  5656566  阅读(98)  评论(0)    收藏  举报