luogu_1155: Sort dual stack

Luo Gu 1155: dual-stack Sort

Description meaning of the questions:

  • Given a length \ (n-\) sequence \ ((n-\ Leq 1000) \) , two initially empty stack, and asked whether the sequence of operation of four rows by ascending order.
  • \ (1: \) if the sequence is not empty, the first element onto the stack \ (S_1 \) . Operation referred to as \ (A \) .
  • \ (2: \) If the stack \ (S_1 \) is not empty, the \ (S_1 \) the top element to eject the output sequence. Operation referred to as \ (D \) .
  • \ (3: \) input sequence is not empty, the first element onto the stack \ (S_2 \) . Operation referred to as \ (C \) .
  • \ (4: \) If the stack \ (S_2 \) is not empty, the \ (S_2 \) the top element to eject the output sequence. Operation referred to as \ (D \) .

Output Description:

  • Output operation sequence lexicographically smallest, if not the nature of the sort dual stack, output \ (0 \) .

Ideas:

  • Write for a long stack monotone greedy + + analog is to be reminded of a bipartite graph.
  • I write a solution to a problem commemorate the passing of three hours.
  • First, there is such a character.
  • If this condition exists \ (i <j <k \ ) and \ (A (K) <A (I) <A (J) \) , then the \ (a (i), a (j) \) can not be in within the same stack, which is a necessary and sufficient condition.
  • prove:
  • Necessity: If \ (i <j <k \ ) and \ (A (K) <A (I) <A (J) \) , then since \ (a (i) \) and \ (a (j ) \) behind there is a smaller number \ (a (K) \) , so \ (a (i), a (j) \) not be popped from the stack. So from the bottom of the stack to the top of the stack of elements is not a monotonically decreasing descending order, then there will pop up when the reverse order, so the \ (a (i), a (j) \) can not be assigned to the same stack.
  • Sufficiency: If \ (a (i), a (j) \) condition is not satisfied, then the conflict will not occur during operation.
    • All particles larger than \ (a (j) \) elements in the stack are constant;
    • All less than \ (a (j) \) elements, for example, \ (A (I) <A (J) \) , due to the absence of the back \ (A (K) <A (I) \) , so \ (a (i) \) have been popped.
    • Therefore, the \ (a (j) \) pushed onto the stack, the stack from the bottom to the top of the stack may be kept still descending, the entire process is carried out smoothly.
  • With the above nature, we only need to meet all the conditions of points into two stacks, this step can be transformed into graph theory problem.
  • Enumerate all points, if \ (i, j \) satisfy the conditions capable of a stack, then \ (i, j \) plus side.
  • Of course enumerate all the points of taking into account the above conditions, a very bad things will happen.
    • I point to the need to enumerate \ (O (n ^ 2) \) time complexity, and I find there is no need to scan backwards smaller number is required (O (n) \) \ time complexity, total it will be \ (O (the n-^ 3) \) , can not pass.
  • To find ways to optimize this step, we can pretreatment \ (f (i) = min (a_j) \) . \ (J \) from \ (I \) to the \ (n-\) .
  • This can be \ (O (n ^ 2) \) enumeration point, determines whether \ (i, j \) satisfy the condition, that is, \ (. 1 + F_ {J} <a_i <a_j \) .
  • Then determines whether a bipartite graph, to determine whether to meet the nature of the dual-stack sort, can be staining.
  • And because the lexicographically smallest requirement, so the priority is assigned to the point \ (S_1 \) in.
  • After sorting analog dual-stack, answer.

Complexity analysis:

  • FIG built enumerate all points \ (O (^ n-2) \) .
  • Staining determined bipartite graph \ (O (n-m +) \) .
  • Analog sorting stack \ (O (n-) \) .
  • The total time complexity is \ (O (^ n-2) \) , can pass.

Code:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 10;
const int INF = 0x3f3f3f3f;
int n, a[maxn], f[maxn];

int head[maxn], ver[maxn<<5], nex[maxn<<5], tot;
inline void add_edge(int x, int y){
    ver[++tot] = y; nex[tot] = head[x]; head[x] = tot;
}

int color[maxn];
bool dfs(int x, int c)
{
    color[x] = c;
    for(int i = head[x]; i; i = nex[i])
    {
        int y = ver[i];
        if(!color[y])
        {
            if(!dfs(y, 3 - c)) return false;
        }
        else if(color[y] == c) return false;
    }
    return true;
}


int main()
{
    scanf("%d", &n); f[n+1] = INF;
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);

    for(int i = n; i >= 1; i--) f[i] = min(f[i+1], a[i]);

    for(int i = 1; i < n; i++)
        for(int j = i + 1; j < n; j++)
        if(a[i] > f[j+1] && a[i] < a[j])
            add_edge(i, j), add_edge(j, i);

    bool flag = true;
    for(int i = 1; i <= n; i++)
    {
        if(!color[i])
        {
            if(!dfs(i, 1))
            {
                flag = false;
                break;
            }
        }
    }

    if(flag == false) puts("0");
    else
    {
        stack<int> stk1, stk2;

        int cnt = 1;
        for(int i = 1; i <= n; i++)
        {

            if(color[i] == 1)
            {
                stk1.push(a[i]);
                printf("a ");
            }
            else{
                stk2.push(a[i]);
                printf("c ");
            }
            while((!stk1.empty() && stk1.top() == cnt) || (!stk2.empty() && stk2.top() == cnt))
            {
                if(!stk1.empty() && stk1.top() == cnt)
                {
                    stk1.pop();
                    cnt++;
                    printf("b ");
                }
                else
                {
                    stk2.pop();
                    cnt++;
                    printf("d ");
                }
            }
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/zxytxdy/p/11755772.html