zoukankan      html  css  js  c++  java
  • 题解 CH1813 【双栈排序】

    题目链接:Link

    Problem

    Solution

    算法提示中说好的栈呢?????
    先考虑单栈排序:显然任意时刻从栈顶到栈底都单调递增,然后我们会发现,对于 $ i < j < k $ ,如果 $ a[k] < a[i] < a[j] $ 肯定不可以单栈排序。考虑到这三个数和他们之间的数字是独立的(这三个数合法那就看别的),不妨拿{1,2,3}举例,可以发现除了{2,3,1}之外都可以单栈排序。
    即“不存在$ a[k] < a[i] < a[j] (i < j < k) $”是有单栈排序的充要条件。
    那么,如果发现了一个非法的三元组{a[i],a[j],a[k]},为了方便起见,我们可以把i和j分开。
    于是,判定的问题就变成了一个二分图染色的问题。
    判定完了后,可以利用染的颜色直接用一个栈进行模拟

    Code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=1005;
    int T,n,a[maxn],co[maxn],s1[maxn],c1,s2[maxn],c2;
    struct JUDGE
    {
    	int k[maxn];
    	struct Edge { int v; Edge *nxt; };
    	Edge mem[maxn*maxn*2],*G[maxn],*ecnt;
    	inline void init()
    	{
    		memset(G,0,sizeof(G)); ecnt=mem;
    		memset(co,0,sizeof(co));
    	}
    	inline void AddEdge(int u,int v) { ecnt->v=v; ecnt->nxt=G[u]; G[u]=ecnt++; }
    	bool dfs(int u,int c)
    	{
    		if(co[u]) return co[u]==c;
    		co[u]=c;
    		for(Edge *it=G[u];it;it=it->nxt) if(!dfs(it->v,3-c)) return false;
    		return true;
    	}
    	bool ok()
    	{
    		k[n+1]=n+1;
    		for(int i=n;i>=1;i--) k[i]=min(k[i+1],a[i]);
    		for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++)
    			if(k[j+1]<a[i]&&a[i]<a[j])
    			{
    				AddEdge(i,j);
    				AddEdge(j,i);
    			}
    		for(int i=1;i<=n;i++) if(!co[i]&&!dfs(i,1)) return false;
    		return true;
    	}
    }jg;
    inline void solve()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    	jg.init();
    	if(!jg.ok()) { puts("0"); return; }
    	int now=1; c1=c2=0;
    	for(int i=1;i<=n;i++)
    	{
    		if(co[i]==1) { s1[c1++]=a[i]; printf("a "); }
    		else { s2[c2++]=a[i]; printf("c "); }
    		while(true)
    		{
    			if(c1&&s1[c1-1]==now) { printf("b "); c1--; now++; }
    			else if(c2&&s2[c2-1]==now) { printf("d "); c2--; now++; }
    			else break;
    		}
    	}
    	puts("");
    }
    int main()
    {
    #ifdef local
    	freopen("pro.in","r",stdin);
    #endif
    	scanf("%d",&T);
    	while(T-->0) solve();
    	return 0;
    }
    
  • 相关阅读:
    网页爬虫小记:两种方式的爬取网站内容
    AOP中使用Aspectj对接口访问权限进行访问控制
    Spring Boot应用总结更新
    SpringBoot集成mybatis配置
    经验收集
    关于阿拉伯文开发的一点经验
    关于IDataReader.GetSchemaTable的一些事情
    removing vmware debugger from visual studio
    SQL Server 2008 R2 附加数据库 “尝试打开或创建物理文件 拒绝访问”的解决办法
    Visual Studio 2013 ReportViewer Control
  • 原文地址:https://www.cnblogs.com/happyZYM/p/11379166.html
Copyright © 2011-2022 走看看