P1750 出栈序列

这好像是普及难度的吧~

感觉再次被小学生吊打了........

\(\color{Red}{----------------------=|(●'◡'●)|=我是手动的分割线----------------------}\)

传送门呢

就是一个出栈序列嘛.........

那么第一次出栈的数字一定是下标1到c中最小的数字,假设它的下标是\(num\)

那么下一次呢??注意这是个栈,其实我们的决策是放入\(1-num\)个数时发现\(a[num]\)很小了,出栈

那么下一次我可以把a[num-1]出栈,也可以在下标为num-1到c+1的地方选一个最小值,作为新的num出栈

\(那么算法很清晰了,设置L=1,R=c两个指针\)

\(每次找到最小的数出栈,标记用过,然后R++,L移到前面一个未被使用的数\)

这样复杂度是\(O(n^2)\)的,找最小值的过程可以用线段树优化到\(O(nlogn)\)

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
typedef long long ll;
ll a[10009],n,c,vis[10009];
int main()
{
	cin>>n>>c;
	for(int i=1;i<=n;i++)	cin>>a[i];
	ll l=1,r=c,ge=0;
	while(ge<n)
	{
		int minn=2*1e9,num;
		for(int i=l;i<=r;i++)
		{
			if(minn>a[i]&&!vis[i])	
				minn=a[i],num=i;
		}
		cout<<a[num]<<" ";
		vis[num]=1,ge++;
		int flag=0;
		for(int j=num-1;j>=1;j--)
		{
			if(vis[j]==0)
			{
				l=j;flag=1;
				break;
			}
		}
		if(r<n)	r++;
		if(flag==0)	l=num+1;//前面没有可用的数字,就不必浪费时间了 
	}
}
posted @ 2020-04-25 11:14  倾叶子佮  阅读(217)  评论(0编辑  收藏  举报