• 【codevs1170】 双栈排序


    http://codevs.cn/problem/1170/ (题目链接)

    题意

      给出一个初始序列,判断能否通过两个栈的入栈和出栈操作构造出一个有序序列。若可以,输出字典序最小的方案。

    Solution

      还是想狙LCF才看的这道题,真的是很神啊。考场绝对做不出的题之一。

      网上题解一大piang,那个结论其实很好YY出来,只是想不到转换到二分图染色上面去。。

    代码

    // codevs1170
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define MOD 100000000
    #define inf 2147483640
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    
    const int maxn=1010;
    struct edge {int to,next;}e[maxn<<1];
    int c[maxn],head[maxn],a[maxn],f[maxn],s1[maxn],s2[maxn];
    int t1,t2,n,cnt;
    
    void link(int u,int v) {
    	e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;
    	e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt;
    }
    bool color(int x,int cl) {
    	c[x]=cl;
    	for (int i=head[x];i;i=e[i].next) {
    		if (!c[e[i].to]) {if (!color(e[i].to,3-cl)) return 0;}
    		else if (c[e[i].to]==cl) return 0;
    	}
    	return 1;
    }
    int main() {
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    	f[n+1]=inf;
    	for (int i=n;i;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]<a[j] && f[j+1]<a[i]) link(i,j);
    	for (int i=1;i<=n;i++)
    		if (!c[i] && !color(i,1)) {puts("0");return 0;}
    	int now=1;
    	for (int i=1;i<=n;i++) {
    		if (c[i]==1) printf("a "),s1[++t1]=a[i];
    		else printf("c "),s2[++t2]=a[i];
    		while (s1[t1]==now || s2[t2]==now) {
    			if (s1[t1]==now) printf("b "),t1--;
    			else printf("d "),t2--;
    			now++;
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    cocos2d游戏jsc文件格式解密,SpideMonkey大冒险
    抖音下载短视频去水印方法
    Metaspliot技术
    WAF bypass
    博客园美化
    Redis未授权访问利用
    网站后台getshell
    OpenVAS
    跨站脚本攻击与防御总结
    相同浏览器同一浏览器多用户登录问题
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/5930693.html
Copyright © 2020-2023  润新知