首页 > 代码库 > 【codevs1170】 双栈排序
【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;}
【codevs1170】 双栈排序
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。