zoukankan      html  css  js  c++  java
  • P1155 [NOIP2008 提高组] 双栈排序

    考虑只有一个栈的话。对于三个数字

    [i<j<k,a_k<a_i<a_j ]

    那么进行栈排序的话,需要i比j先出栈,k比i,j先出栈,这就产生矛盾了。需要在增加一个栈来了。
    显然i,j不能在同一个栈进行排序。所以要分开
    我们对于这种情况,在i,j之间连边。跑二分图染色,染色失败则无解.

    这题还要求输出字典序最小的操作,push操作的优先级更高,只到栈不合法的时候才pop,就是栈顶到栈底不再单调递增的时候就是非法,要pop。再向第二个栈push的时候,我们要判断第一个栈能不能pop,这样字典序更小.最后按顺序模拟出栈

    const int N = 1e3 + 79;
    int n, a[N], color[N];
    
    std::stack<int>s[2];
    int pos(1);
    
    struct graph {
    	int head[N], tot = 1, next[N << 1], ver[N << 1];
    	inline void add(int a, int b) {
    		ver[++tot] = b;
    		next[tot] = head[a];
    		head[a] = tot;
    	}
    } G;
    int smin[N];
    int q[N];
    
    
    inline bool Pop(int id) {
    	if(s[id].size() && s[id].top() == pos) {
    		putchar(id ? 'd' : 'b');
    		s[id].pop();
    		putchar(' ');
    		++pos;
    		return true;
    	}
    	return false;
    }
    
    inline void Push(int x, int id) {
    	if(id == 1) {
    		while(Pop(0));
    	}
    	while(s[id].size() && s[id].top() < x) {
    		if(!Pop(id)) {
    			Pop(id ^ 1);
    		}
    	}
    	if(id == 1) {
    		while(Pop(0));
    	}
    	s[id].push(x);
    	putchar(id ? 'c' : 'a');
    	putchar(' ');
    }
    
    
    
    int main() {
    
    	read(n);
    	rep(i, 1, n) {
    		read(a[i]);
    	}
    	smin[n + 1] = n + 1;
    	drp(i, n, 1) {
    		smin[i] = min(smin[i + 1], a[i]);
    	}
    	memset(color, 0xff, sizeof color);
    	rep(i, 1, n) {
    		rep(j, i + 1, n) {
    			if(smin[j + 1] < a[i] && a[i] < a[j]) {
    				G.add(i, j);
    				G.add(j, i);
    			}
    		}
    	}
    
    	rep(i, 1, n) {
    		if(!~color[i]) {
    			q[q[0] = 1] = i;
    			color[i] = 0;
    			rep(kkk, 1, q[0]) {
    				int x = q[kkk];
    				repg(x) {
    					int y(G.ver[i]);
    					if(~color[y] && color[y] != (color[x] ^ 1)) {
    						puts("0");
    						return 0;
    					}
    					if(!~color[y]) {
    						q[++q[0]] = y;
    						color[y] = color[x] ^ 1;
    
    					}
    				}
    			}
    		}
    	}
    	rep(i, 1, n) {
    		Push(a[i], color[i]);
    	}
    
    
    	while(s[0].size() || s[1].size()) {
    		Pop(0);
    		Pop(1);
    	}
    	return 0;
    }
    

    本文来自博客园,作者:{2519},转载请注明原文链接:https://www.cnblogs.com/QQ2519/p/15473224.html

  • 相关阅读:
    sql server profiler 对TextData进行过滤
    简单账表"小计"无法正常显示
    从字符串转换日期和/或时间时,转换失败。
    [转载]Java中的final与static的区别
    POI Excel导出样式设置
    [转载]poi 设置Region后单元格边框不起作用
    [转载]将java程序编译成独立运行的exe文件
    Java 线程安全问题—synchronized锁机制
    彻底理解ThreadLocal
    ThreadLocal封装Connection,实现同一线程共享资源
  • 原文地址:https://www.cnblogs.com/QQ2519/p/15473224.html
Copyright © 2011-2022 走看看