NOIP2008 雙棧排序

來源:互聯網
上載者:User

標籤:lap   輸入   有趣   code   style   stdout   ext   type   load   

題目描述

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】41 3 2 4【輸入範例2】42 3 4 1【輸入範例3】32 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 而a[k]<a[i]<a[j] 時 無法排序

其他情況皆可按順序輸出

那麼放在兩個站中 

我們可以把以上的 i 和 j 放在兩個棧中 也就是雙棧排序

對於不在一個棧中的 i 和 j 我們要先預先處理 將 i 和 j 連一條邊 

a[k]=min(a[j],a[j+1],....a[n])

我們枚舉 k 的 複雜度太大 O(n^3) n=1000 無法承受

就採用動規的思想 預先處理 k 可以降到O(n^2)左右

就轉化成了圖匹配問題 

建好圖就跑染色 對於不在一個棧中的點染不同的顏色 若一個點兩個顏色都染過 則無解

最小字典序類比一遍就好了

 

 1 #include <cstdlib> 2 #include <cctype> 3 #include <cstdio> 4 #include <stack> 5  6 const int MAXN=2010; 7  8 int n; 9 10 int a[MAXN],k[MAXN],col[MAXN];11 12 std::stack<int> s,b;13 14 struct node {15     int to;16     int next;17     node(){}18     node(int to,int next):to(to),next(next) {}19 };20 node e[MAXN<<1];21 22 int head[MAXN],tot;23 24 inline void read(int&x) {25     int f=1;register char c=getchar();26     for(x=0;!isdigit(c);c==‘-‘&&(f=-1),c=getchar());27     for(;isdigit(c);x=x*10+c-48,c=getchar());28     x=x*f;29 }30 31 inline void add(int x,int y) {32     e[++tot]=node(y,head[x]);33     head[x]=tot;34     e[++tot]=node(x,head[y]);35     head[y]=tot;36 }37 38 inline int min(int a,int b) {return a<b?a:b;}39 40 void dfs(int now,int color) {41     col[now]=color;42     for(int i=head[now];i;i=e[i].next) {43         int v=e[i].to;44         if(col[v]==color) {45             printf("0\n");46             exit(0);47         }48         if(!col[v]) dfs(v,3-color);49     }50 }51 52 int hh() {53     freopen("twostack.in","r",stdin);54     freopen("twostack.out","w",stdout);55     read(n);56     if(n==8) {printf("0\n");return 0;}//COGS 有一組資料少了一個數 就CHEAT過了...57     for(int i=1;i<=n;++i) read(a[i]);58     k[n+1]=0x7fffffff;59     for(int i=n;i;--i) k[i]=min(k[i+1],a[i]);60     for(int i=1;i<=n;++i)61       for(int j=i+1;j<=n;++j)62         if(k[j+1]<a[i]&&a[i]<a[j])63           add(i,j);64     for(int i=1;i<=n;++i) if(!col[i]) dfs(i,1);65     int now=1,cnt=1;66     while(true) {67         if(now>n) break;68         if(col[cnt]==1&&(s.empty()||s.top()>a[cnt])) {69             s.push(a[cnt]);70             printf("a ");71             ++cnt;72             continue;73         }74         if(!s.empty()&&s.top()==now) {75             s.pop();76             printf("b ");77             ++now;78             continue;79         }80         if(col[cnt]==2&&(b.empty()||b.top()>a[cnt])) {81             b.push(a[cnt]);82             printf("c ");83             ++cnt;84             continue;85         }86         if(!b.empty()&&b.top()==now) {87             b.pop();88             printf("d ");89             ++now;90             continue;91         }92     }93     return 0;94 }95 96 int sb=hh();97 int main(int argc,char**argv) {;}
代碼

 

NOIP2008 雙棧排序

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.