p1321双栈排序(noip2008)

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/84666913

题目

https://www.luogu.org/problemnew/show/P1155

题解

二分图判定+模拟题目要求的双栈进出

代码

#include<bits/stdc++.h>
using namespace std;
const int inf=0x7f7f7f7f;
const int __=1010;
inline int read()
{
	int f=1,num=0;
	char ch=getchar();
	while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); }
	while (isdigit(ch)) num=(num<<1)+(num<<3)+(ch^48), ch=getchar();
	return num*f;
}

vector<int> e[__];//用了不定数组来建立邻接表
stack<int> s1,s2;
int f[__],a[__];
int color[__];

void bfs(int s)
{
	queue<int>q;
	q.push(s);
	color[s]=1;
	while (!q.empty())
	{
		int x=q.front();
		for (int i=0;i<e[x].size();++i)
		{
			int y=e[x][i];
			if (color[y]==-1)
			{
				color[y]=color[x]^1;
				q.push(y);
			}
			else if (color[y]!=(color[x]^1))
			{
				cout<<0;
				exit(0);
			}
		}
		q.pop();
	}
}
int main()
{
	//读入数据 
	memset(color,-1,sizeof(color));
	int n=read();
	for (int i=1;i<=n;++i)
		a[i]=read();
		
	/*
		用动态规划的思想,将上述复杂度降到O(n^2)
		状态:f[i]=min(a[i],a[i+1], ... ,a[n])
		边界条件:f[n+1]=INF;
		状态转移方程:f[i]=min(f[i+1],a[i])
		于是下述判断就转化为了 f[j+1]<a[i] && a[i]<a[j]
	*/	
	f[n+1]=inf;
	for (int i=n;i>=1;--i)
		f[i]=min(f[i+1],a[i]);
	for(int i=1; i<=n; ++i)
        for(int j=i+1; j<=n; ++j)
            if(a[i]>f[j+1] && a[i]<a[j])
                e[i].push_back(j),e[j].push_back(i);
                
    //二分图染色 
    for (int i=1;i<=n;++i)
    	if (color[i]==-1)
    		bfs(i);
    		
    //开始模拟双栈排序 
	int cnt=1;
    for (int i=1;i<=n;++i)
    {
    	if (color[i]==1)
    	{
    		s1.push(a[i]);//染成黑色的进入一栈 
    		cout<<"a ";
		}
		else
		{
			s2.push(a[i]);//染成白色的进入二栈 
			cout<<"c ";
		}
		while ((!s1.empty()&&s1.top()==cnt) || (!s2.empty()&&s2.top()==cnt))
		{
			if (!s1.empty()&&s1.top()==cnt)
			{
				s1.pop();
				cout<<"b ";
			}
			else
			{
				s2.pop();
				cout<<"d ";
			}
			++cnt;
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/84666913
今日推荐