• 双栈排序


     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 const int maxn=1007;
     5 const int INF=2147483647; 
     6 int a[maxn],imin[maxn],col[maxn],n,num;
     7 int stk1[maxn],stk2[maxn],top1,top2,head[maxn];
     8 struct Edge{
     9     int next,to;
    10 }edge[maxn*maxn*10];
    11 void add(int from,int to){
    12     edge[++num].next=head[from];
    13     edge[num].to=to;
    14     head[from]=num;
    15 }
    16 bool dfs(int x){
    17     for(int i=head[x];i;i=edge[i].next){
    18         int v=edge[i].to;
    19         if(!col[v]){
    20             col[v]=col[x]^1;
    21             if(!dfs(v)) return false;
    22         }
    23         else if(col[v]==col[x]) return false;
    24     }
    25     return true;
    26 }
    27 int main(){
    28     cin>>n;
    29     for(int i=1;i<=n;i++) cin>>a[i];imin[n+1]=INF;
    30     for(int i=n;i>=1;i--) imin[i]=min(imin[i+1],a[i]); 
    31     for(int i=1;i<=n;i++){
    32         for(int j=i+1;j<=n;j++){
    33             if(a[i]<a[j]&&a[i]>imin[j+1]){
    34                 add(i,j);add(j,i);
    35             }
    36         }
    37     }
    38     for(int i=1;i<=n;i++){
    39         if(!col[i]){
    40             col[i]=2;
    41             if(!dfs(i)) {cout<<0<<endl;return 0;}
    42         }
    43     }
    44     int cnt=1;
    45     for(int i=1;i<=n;i++){
    46         if(col[i]==2) {stk1[++top1]=a[i];cout<<"a ";}
    47         else {stk2[++top2]=a[i];cout<<"c ";}
    48         while(top1&&stk1[top1]==cnt||top2&&stk2[top2]==cnt){
    49             if(stk1[top1]==cnt){cout<<"b ";top1--;}
    50             else {cout<<"d ";top2--;}
    51             ++cnt;
    52         }
    53     }
    54     return 0;
    55 } 

     来自five20

    本题二分图染色+栈模拟。  

      若我们知道每个数应该放在哪个栈中,就可以去模拟了。

      考虑数ai,aj,ak不能在同一栈的情况,若i<j<k,ai<aj,ai>aki<j<k,ai<aj,ai>ak那么i,ki,k是肯定不能在同一栈内的,我们对二元组建边,那么就是个二分图染色的模型了。

      由于要字典序最小,所以每次染色时另当前未被染色的位置为栈1再去dfs,染色后每个位置所在的栈就确定了。

      然后就是纯模拟咯。

      (安利一个神奇的调试技巧:用iostream库下的cerr代替cout,在评测机测试时会直接跳过这条输出语句,但在终端可以输出,这样就能防止忘记删调试语句而写挂!>.^_^.<)

  • 相关阅读:
    定时器的应用---查询方式---让8个LED灯,左右各4个来回亮
    单片机实现60s定时器
    单片机不同晶振怎么计算延迟时间?
    573锁存器驱动8段数码管
    51单片机英文引脚等中文对照
    Java【小考】
    viso2010从mysql中导出ER图
    驱动继电器实验
    驱动蜂鸣器的实验
    驱动数码管的实验
  • 原文地址:https://www.cnblogs.com/lcan/p/9615378.html
Copyright © 2020-2023  润新知