NOIP2008【雙棧排序】_類比

來源:互聯網
上載者:User
Description

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希望知道其中字典序最小的操作序列是什麼 Input Format

輸入檔案twostack.in的第一行是一個整數n。 第二行有n個用空格隔開的正整數,構成一個1~n的排列 Output Format

輸出檔案twostack.out共一行,如果輸入的排列不是“可雙棧排序排列”,輸出數字0;否則輸出字典序最小的操作序列,每兩個操作之間用空格隔開,行尾沒有空格 Sample Input

【輸入範例1】41 3 2 4【輸入範例2】42 3 4 1【輸入範例3】32 3 1
Sample Output
輸出範例1a b a a b b a b輸出範例20輸出範例3a c a b b d
Hint

【限制】30%的資料滿足: n<=10

50%的資料滿足: n<=50

100%的資料滿足: n<=1000

【題解】

個人覺得這題想法有點難(反正我是想不到)

二分圖染色+類比

先對每一對永遠都不可能進同一個棧的兩個數建邊( 若存在k,滿足i<j<k,使得S[k]<S[i]<S[j]則i,j永遠不能再同一個棧)

對這張圖進行二分圖染色(這樣就可以把矛盾的兩個數分在兩個棧裡面了)如果是二分圖則可以雙棧排序(接下來輸出就是類比了)

染色的時候 按編號遞增尋找未染色的點初始顏色為0,這樣可以保證字典序

詳見代碼

#include <algorithm>#include <iostream>#include <cstdlib>#include <cstring>#include <string>#include <cstdio>#include <queue>#include <ctime>#include <cmath>#include <vector>using namespace std;int i,j,k,l,m,n,pd,b;int a[1005],col[1005],s[3][1005],num[3];vector <int> road[1005];void work(int u)  {    if (pd==1) return;    for (int i=0;i<road[u].size();i++)      {      int v=road[u][i];      if (!col[v]) col[v]=3-col[u],work(v);      if (col[v]!=3-col[u]) {b=0;pd=1;return;}  }  }int main()  {  scanf("%d",&n);  for (i=1;i<=n;i++) scanf("%d",&a[i]);  k=1e9;  for (j=n;j;j--)    {    k=min(k,a[j]);    for (i=1;i<=j-1;i++)      if (a[i]<a[j]&&a[i]>k) road[i].push_back(j),road[j].push_back(i);  }b=1;for (i=1;i<=n;i++)  {    if (!col[i]) col[i]=1,pd=0,work(i);     if (b==0) {printf("0");return 0;}      }    for (j=i=1;i<=n;i++)      {      if (col[i]==1) printf("a ");else printf("c ");      s[col[i]][++num[col[i]]]=i;      for (;a[s[1][num[1]]]==j||a[s[2][num[2]]]==j;j++)   {    if (a[s[1][num[1]]]==j) printf("b "),--num[1];    else printf("d "),--num[2];   }   }  } 


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.