洛谷 P1155 双栈排序
题目传送门
解题思路:
首先考虑只有一个栈的时候如何解决这个问题。
就是对于一对位置 (i, j)是否能共存三个位置 i<j<k 存在pk<pi<pj 是不可行的,因为pk 需要在 pi 与pj 之前出栈,但 pi 又需要在 pj 之前出栈,那么这就会产生矛盾。
我们就将i和j连一条边,如果找到一对i和j不能连边,构不成二分图,输出0;否则贪心模拟做题过程.
AC代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<queue> 5 #include<vector> 6 #include<stack> 7 #include<cstdlib> 8 #define INF 0x7f7f7f7f 9 10 using namespace std; 11 12 int n,a[1005],f[1005],color[1005]; 13 vector<int> e[1005]; 14 stack<int> s1,s2; 15 16 inline void bfs(int s) { 17 queue<int> q; 18 q.push(s); 19 color[s] = 1; 20 while(!q.empty()) { 21 int now = q.front(); 22 for(int i = 0;i < e[now].size(); i++) { 23 int next = e[now][i]; 24 if(color[next] == -1) { 25 color[next]= color[now] ^ 1; 26 q.push(next); 27 } 28 else if(color[next] != (color[now] ^ 1)) { 29 printf("0"); 30 exit(0); 31 return ; 32 } 33 } 34 q.pop(); 35 } 36 } 37 38 int main() 39 { 40 memset(color,-1,sizeof(color)); 41 scanf("%d",&n); 42 for(int i = 1;i <= n; i++) 43 scanf("%d",&a[i]); 44 f[n+1] = INF; 45 for(int i = n;i >= 1; i--) 46 f[i] = min(f[i+1],a[i]); 47 for(int i = 1;i <= n; i++) 48 for(int j = i + 1;j <= n; j++) 49 if(a[i] > f[j+1] && a[i] < a[j]) 50 e[i].push_back(j),e[j].push_back(i); 51 for(int i = 1;i <= n; i++) 52 if(color[i] == -1) 53 bfs(i); 54 int cnt = 1; 55 for(int i = 1;i <= n; i++) { 56 if(color[i] == 1) { 57 s1.push(a[i]); 58 printf("a "); 59 } 60 else { 61 s2.push(a[i]); 62 printf("c "); 63 } 64 while((!s1.empty() && s1.top() == cnt) || (!s2.empty() && s2.top() == cnt)) { 65 if(!s1.empty() && s1.top() == cnt) { 66 s1.pop(); 67 printf("b "); 68 } 69 else { 70 s2.pop(); 71 printf("d "); 72 } 73 ++cnt; 74 } 75 } 76 return 0; 77 }
//NOIP提高2008 T4