zoukankan      html  css  js  c++  java
  • poj2090

    题意:给一个数列,两个栈,要求数列从后往前依次入栈,问能否使出栈序列是不减的。(双栈排序)

    分析:利用二分图染色法。

    首先观察那些牌绝对不能压入同一个栈,若两个不能入同一栈则连一条边,然后根据二分图染色,看是否能构成二分图。如果不能直接输出impossible

    两张牌i,j不能入同一栈的充要条件是,i>j>k(i最先入栈) && stock[k]<stock[i]<stock[j]

    然后根据每个点所染的颜色决定把每个牌压入哪个栈。然后模拟即可。

    View Code
    #include <iostream>
    #include
    <cstdio>
    #include
    <cstdlib>
    #include
    <cstring>
    #include
    <algorithm>
    usingnamespace std;

    #define maxn 250

    struct Edge
    {
    int v, next;
    } edge[maxn
    * maxn];

    int n;
    int stock[maxn], f[maxn];
    int head[maxn], ecount, color[maxn], q[maxn];
    intout[maxn];
    bool ok;
    int stk1[maxn], stk2[maxn];
    int top1, top2, step;

    void input()
    {
    for (int i =0; i < n; i++)
    {
    scanf(
    "%d", &stock[i]);
    out[i] = stock[i];
    }
    }

    void addedge(int&a, int&b)
    {
    edge[ecount].next
    = head[a];
    edge[ecount].v
    = b;
    head[a]
    = ecount++;
    }

    void bfs(int&s)
    {
    int front =0;
    int rear =1;
    q[
    0] = s;
    color[s]
    =1;
    while (front != rear)
    {
    int a = q[front++];
    for (int i = head[a]; i !=-1; i = edge[i].next)
    {
    int b = edge[i].v;
    if (!color[b])
    {
    q[rear
    ++] = b;
    color[b]
    =3- color[a];
    }
    elseif (color[a] == color[b])
    {
    ok
    =false;
    return;
    }
    }
    }
    }

    void make(int i)
    {
    int a = stock[i];
    bool did =true;
    while (did)
    {
    did
    =false;
    if (top1 >0&& stk1[top1 -1] ==out[step])
    {
    top1
    --;
    printf(
    "pop 1\n");
    step
    ++;
    did
    =true;
    }
    if (top2 >0&& stk2[top2 -1] ==out[step])
    {
    top2
    --;
    printf(
    "pop 2\n");
    step
    ++;
    did
    =true;
    }
    }
    if (i <0)
    return;
    if (color[i] ==1)
    {
    stk1[top1
    ++] = a;
    printf(
    "push 1\n");
    }
    else
    {
    stk2[top2
    ++] = a;
    printf(
    "push 2\n");
    }
    }

    void print()
    {
    top1
    = top2 =0;
    step
    =0;
    for (int i = n -1; i >=0; i--)
    make(i);
    make(
    -1);
    }

    void work()
    {
    memset(head,
    -1, sizeof(head));
    f[
    0] = stock[0];
    for (int i =1; i < n; i++)
    f[i]
    = min(f[i -1], stock[i]);
    ecount
    =0;
    for (int i =1; i < n -1; i++)
    {
    for (int j = i +1; j < n; j++)
    {
    if (stock[j] >= stock[i])
    continue;
    if (stock[j] > f[i -1])
    {
    addedge(i, j);
    addedge(j, i);
    }
    }
    }
    ok
    =true;
    memset(color,
    0, sizeof(color));
    for (int i =0; i < n; i++)
    {
    if (!color[i])
    bfs(i);
    if (!ok)
    {
    printf(
    "impossible\n");
    return;
    }
    }
    print();
    }

    int main()
    {
    //freopen("t.txt", "r", stdin);
    int t =0;
    while (scanf("%d", &n), n)
    {
    t
    ++;
    printf(
    "#%d\n", t);
    input();
    sort(
    out, out+ n);
    work();
    }
    return0;
    }
  • 相关阅读:
    补题列表
    task list
    UVa 11809
    UVA 272 TEX Quotes 题解
    莱州一中2016高考加油视频
    POJ2367-Genealogical tree-拓扑排序
    POJ1094-Sorting It All Out-拓扑排序
    POJ3660-Permutations-传递闭包FLOYD
    POJ3687- Labeling Balls-优先队列拓扑排序
    POJ1201-Intervals- 差分约束
  • 原文地址:https://www.cnblogs.com/rainydays/p/2124245.html
Copyright © 2011-2022 走看看