题目描述

Tom最近在研究一个有趣的排序问题。如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序。

操作a

如果输入序列不为空,将第一个元素压入栈S1

操作b

如果栈S1不为空,将S1栈顶元素弹出至输出序列

操作c

如果输入序列不为空,将第一个元素压入栈S2

操作d

如果栈S2不为空,将S2栈顶元素弹出至输出序列

如果一个1~n的排列P可以通过一系列操作使得输出序列为1,2,…,(n-1),n,Tom就称P是一个“可双栈排序排列”。例如(1,3,2,4)就是一个“可双栈排序序列”,而(2,3,4,1)不是。下图描述了一个将(1,3,2,4)排序的操作序列:<a,c,c,b,a,d,d,b>

当然,这样的操作序列有可能有几个,对于上例(1,3,2,4),<a,c,c,b,a,d,d,b>是另外一个可行的操作序列。Tom希望知道其中字典序最小的操作序列是什么。

输入输出格式

输入格式:

输入文件twostack.in的第一行是一个整数n。

第二行有n个用空格隔开的正整数,构成一个1~n的排列。

输出格式:

输出文件twostack.out共一行,如果输入的排列不是“可双栈排序排列”,输出数字0;否则输出字典序最小的操作序列,每两个操作之间用空格隔开,行尾没有空格。

输入输出样例

输入样例#1:

【输入样例1】
4
1 3 2 4
【输入样例2】
4
2 3 4 1
【输入样例3】
3
2 3 1

输出样例#1:

【输出样例1】
a b a a b b a b
【输出样例2】
0
【输出样例3】
a c a b b d

说明

30%的数据满足: n<=10

50%的数据满足: n<=50

100%的数据满足: n<=1000

如果满足 i<j<k &&num[i]<num[j],num[i]>num[k]就不能单栈排序并考虑双栈

  如果 不是二分图 就不能双栈排序

最后模拟输出  ————我居然在模拟上卡了很长时间!!

  1 #include <algorithm>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <queue>
  5
  6 using namespace std;
  7
  8 const int N(1000+15);
  9 int n,num[N],pre,mi[N];
 10
 11 int head[N],sumedge;
 12 struct Edge
 13 {
 14     int u,v,next;
 15     Edge(int u=0,int v=0,int next=0):
 16         u(u),v(v),next(next){}
 17 }edge[N<<1];
 18 void ins(int u,int v)
 19 {
 20     edge[++sumedge]=Edge(u,v,head[u]);
 21     head[u]=sumedge;
 22 }
 23
 24 int col[N],st1[N],st2[N],to1,to2;
 25 void Paint_(int s)
 26 {
 27     col[s]=0;
 28     queue<int>que;
 29     que.push(s);
 30     while(!que.empty())
 31     {
 32         pre=que.front();que.pop();
 33         for(int i=head[pre];i;i=edge[i].next)
 34         {
 35             int to=edge[i].v;
 36             if(col[to]!=-1)
 37             {
 38                 if(col[to]==col[pre])
 39                 {
 40                     puts("0");
 41                     exit(0);
 42                 }
 43             }
 44             else
 45             {
 46                 col[to]=col[pre]^1;
 47                 que.push(to);
 48             }
 49         }
 50     }
 51 }
 52
 53 int main()
 54 {
 55     scanf("%d",&n);
 56     for(int i=1;i<=n;i++)
 57         scanf("%d",num+i);
 58     mi[n+1]=1e7;
 59     for(int i=n;i>=1;i--)
 60         mi[i]=min(mi[i+1],num[i]);
 61     for(int i=1;i<n;i++)
 62       for(int j=i+1;j<=n;j++)
 63           if(num[i]<num[j]&&num[i]>mi[j+1])
 64                  ins(i,j),ins(j,i);
 65     memset(col,-1,sizeof(col));
 66     for(int i=1;i<=n;i++)
 67         if(col[i]==-1) Paint_(i);
 68     int now_min=1;
 69     for(int i=1;i<=n;i++)
 70     {
 71         if(col[i]==0)
 72         {
 73             if(num[i]==now_min)
 74             {
 75                 printf("a b "),now_min++;
 76                 if(st1[to1]==num[i]) to1--;
 77             }
 78             else if(!to1||st1[to1]>num[i])
 79                 st1[++to1]=num[i],printf("a ");
 80             for(;to1&&st1[to1]==now_min;)
 81                 printf("b "),to1--,now_min++;
 82         }
 83         else
 84         {
 85             if(num[i]==now_min)
 86             {
 87                 printf("c d "),now_min++;
 88                 if(st1[to1]==num[i]) to1--;
 89             }
 90             else if(!to2||st2[to2]>num[i])
 91                 st2[++to2]=num[i],printf("c ");
 92             for(;to2&&st2[to2]==now_min;)
 93                 printf("d "),to2--,now_min++;
 94         }
 95     }
 96     for(;now_min<=n;now_min++)
 97     {
 98         for(;st1[to1]==now_min;to1--) printf("b ");
 99         for(;st2[to2]==now_min;to2--) printf("d ");
100     }
101     return 0;
102 }

转载于:https://www.cnblogs.com/Shy-key/p/6978154.html

洛谷——P1155 双栈排序相关推荐

  1. 二分图——洛谷P1155 双栈排序

    https://daniu.luogu.org/problem/show?pid=1155 二分图染色+模拟 1.首先考虑一个简单情况--单栈排序,显然有这样的一个事实: a[i]和a[j] 不能压入 ...

  2. 洛谷P1155 双栈排序

    这题什么毒瘤......之前看一直没思路,然后心说写个暴搜看能有多少分,然后就A了??! 题意:给你一个n排列,求它们能不能通过双栈来完成排序.如果能输出最小字典序方案. [update]这里面加了一 ...

  3. P1155 双栈排序(二分图的染色判断+链式前向星)

    P1155 双栈排序 让字典序最小,当然尽量进S1 那什么时候必须进S2呢? a[i]和a[j] 不能压入同一个栈⇔存在一个k,使得i<j<k且a[k]<a[i]<a[j] 因 ...

  4. P1155 双栈排序(二分图染色)

    P1155 双栈排序(二分图染色) 题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一 ...

  5. P1155 双栈排序

    P1155 双栈排序 题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S ...

  6. LOJ P1155 双栈排序 二分图染色 图论

    https://www.luogu.org/problem/show?pid=P1155 题解: https://www.byvoid.com/zhs/blog/noip2008-twostack 开 ...

  7. AC日记——双栈排序 洛谷 P1155

    双栈排序 思路: 二分图染+模拟: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1005 #define ...

  8. NOIP2008 双栈排序

    https://www.luogu.org/problem/show?pid=1155 题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输 ...

  9. 【每日一题】8月7日题目精讲—双栈排序

    来源:牛客网 文章目录 题目描述 题意: 题解: 代码: 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他语言262144K 64bit IO Format: %l ...

最新文章

  1. php实现tail,Linux-如何用php实现Linux下的tail -f命令?
  2. 我的Go+语言初体验——go【Format】goplus
  3. JAVA进制及进制之间的转换
  4. 【389天】跃迁之路——程序员高效学习方法论探索系列(实验阶段146-2018.03.01)...
  5. c++实验总结_高考化学选三简答题总结6——配位化合物、配位键、配位数
  6. Android系统启动-SystemServer下篇
  7. Pandas系列(二)查询数据
  8. allennlp0.9.0问题
  9. Windows移动热点服务
  10. tomcat8下载安装教程
  11. 亚马逊全站点、全类目产品爬取,支持批量品牌注册查询,独家技术防屏蔽节省大量选品分析时间,全自动无人值守运行
  12. octet-stream文件怎么看
  13. 高斯消元法(matlab)
  14. 计算机音乐谱恋人心,天刀曲谱大全_天涯明月刀曲谱恋人心
  15. 成语接龙 给一个很大的成语库 如何找出其中最长的一条线
  16. iPhone 14 全系售价及配置曝光,绝了!
  17. word段落居中的快捷键_word里段落的快捷键 WORD中段落的快捷键是什么
  18. php实现教学卡片,如何实现卡片翻阅效果
  19. mysql查询一个字段最大值_查询表中某一个字段的数字最大值的记录
  20. 毛笔笔刷书法签名手写字体设计 Brightwall – Brush Signature Font

热门文章

  1. tcga数据下载_手把手教你用R下载TCGA数据:CGDSR包
  2. SQL Server高级查询之数据查询和操作(DDL和DML)
  3. 二叉搜索树第k小元素
  4. window.onload和jQuery的ready函数区别
  5. Python入门--元组的创建,(),tuple()
  6. angular学习笔记
  7. python列表内元素求和_Python之list对应元素求和
  8. [leetcode]5337. 每个元音包含偶数次的最长子字符串
  9. 牛客练习赛20:A. 礼物(组合数学/小球与盒子问题)
  10. “玲珑杯”郑州轻工业学院第八届ACM程序设计大赛Problem G: 蛤玮点菜