codevs 1170 双栈排序
Posted 一入OI深似海
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs 1170 双栈排序相关的知识,希望对你有一定的参考价值。
/* 好题啊 好题啊 而然还是看了一眼题解啊 有那么一点思路 但是离写出代码还很远 考虑必须分开放倒两个栈里的情况 即存在i<j<k 有 a[k]<a[i]<a[j] 这里RMQ n*n搞一下 那如果出现 a b 不在一块 b c 不在一块 a c 不在一块 那么两个栈显然办不了了 所以嘛 因为只有俩栈 染色吧那就 染完判一下输出0的情况 同时不相邻的那些的块块 按字典序染 然后就就模拟一下 就像个普通的火车进站类似的题 只不过有两个栈 注意当可以进2出1的时候 先出1 这样字典序小 (感觉到了字典序深深地恶意) */ #include<iostream> #include<cstdio> #include<cstring> #define maxn 1010 using namespace std; int n,m,a[maxn],num,head[maxn],color[maxn],mx[maxn][25],P[maxn],falg; int s1[maxn],top1,s2[maxn],top2; struct node{ int v,pre; }e[maxn*maxn*2]; int max(int x,int y){ return x>y?x:y; } void Add(int from,int to){ num++;e[num].v=to; e[num].pre=head[from]; head[from]=num; } void Insert(){ memset(mx,127/3,sizeof(mx)); for(int i=1;i<=n;i++)mx[i][0]=a[i]; for(int j=1;j<=20;j++) for(int i=1;i+(1<<j)-1<=n;i++) mx[i][j]=min(mx[i][j-1],mx[i+(1<<j-1)][j-1]); } void Get(){ for(int i=1;i<=n;i++) for(int j=0;j<=20;j++) if((1<<j)>i){ P[i]=j-1;break; } } int Query(int l,int r){ int k=P[r-l+1]; return min(mx[l][k],mx[r-(1<<k)+1][k]); } int Dfs(int x){ for(int i=head[x];i;i=e[i].pre){ int v=e[i].v; if(color[v]==0){ color[v]=3-color[x]; if(!Dfs(v))return 0; } else if(color[v]==color[x])return 0; } return 1; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); Insert();Get(); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++){ if(a[i]>a[j])continue; int mx=Query(j+1,n); if(mx<a[i])Add(a[i],a[j]),Add(a[j],a[i]); } for(int i=1;i<=n;i++) if(color[i]==0){ color[i]=1; if(!Dfs(i)){falg=1;break;} } if(falg==1){printf("0\n");return 0;} int now=1; for(int i=1;i<=n;i++){ if(color[a[i]]==1){ if(a[i]==now){printf("a b ");now++;} else{ while(a[i]>s1[top1]&&top1){ top1--;printf("b "); } s1[++top1]=a[i];printf("a "); } } else { if(a[i]==now){printf("c d ");now++;} else{ while(a[i]>s2[top2]&&top2){ top2--;printf("b "); } while(s1[top1]==now){ top1--;printf("b ");now++; } s2[++top2]=a[i];printf("c "); } } } for(int i=now;i<=n;i++){ while(top1&&i==s1[top1]){ top1--;printf("b "); } while(top2&&i==s2[top2]){ top2--;printf("d "); } } return 0; }
以上是关于codevs 1170 双栈排序的主要内容,如果未能解决你的问题,请参考以下文章
2017.2.18[codevs1170]NOIP2008提高组复赛T4双栈排序