洛谷 P1160 队列安排

洛谷 P1160 队列安排

Description

  • 一个学校里老师要将班上N个同学排成一列,同学被编号为1∼N,他采取如下的方法:

    1. 先将1号同学安排进队列,这时队列中只有他一个人;

    2. 2−N号同学依次入列,编号为i的同学入列方式为:老师指定编号为i的同学站在编号为1∼(i−1)中某位同学(即之前已经入列的同学)的左边或右边;

    3. 从队列中去掉M(M

    在所有同学按照上述方法队列排列完毕后,老师想知道从左到右所有同学的编号。

Input

  • 第1行为一个正整数N,表示了有N个同学。

    第2−N行,第i行包含两个整数k,p,其中k为小于i的正整数,p为0或者1。若p为0,则表示将i号同学插入到k号同学的左边,p为1则表示插入到右边。

    第N+1行为一个正整数M,表示去掉的同学数目。

    接下来M行,每行一个正整数x,表示将x号同学从队列中移去,如果x号同学已经不在队列中则忽略这一条指令。

Output

  • 1行,包含最多NNN个空格隔开的正整数,表示了队列从左到右所有同学的编号,行末换行且无空格。

Sample Input

4
1 0
2 1
1 0
2
3
3

Sample output

2 4 1

题解:

  • 1年前,写链表,越写越乱,爆炸。
  • 现在,看到这题,想着还有什么别的思路。
  • 然后我就用写出来了,写完后发现用树的思路更清晰、更容易
  • 我以后链表的题都要用树写!
  • 树的思路就是左边就放左儿子,右边就放右儿子,删除某个点就给那个点打个标记,输出时碰到标记就不输出好了。输出时中序输出
#include 
#include 
#define maxn 100005
using namespace std;

struct Tree {int son1, son2;} tree[maxn * 4];
int n, m;
bool vis[maxn];

int read()
{
    int x = 0; char c = getchar();
    while(c < '0' || c > '9') c = getchar();
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
    return x;
}

void dfs(int x)
{
    if(tree[x].son1) dfs(tree[x].son1);
    if(!vis[x]) printf("%d ", x);
    if(tree[x].son2) dfs(tree[x].son2);
}

int main()
{
    cin >> n;
    for(int i = 2; i <= n; i++)
    {
        int x = read(), op = read();
        if(op == 0)
        {
            if(tree[x].son1)
            {
                int t = tree[x].son1;
                tree[x].son1 = i;
                tree[i].son1 = t;
            }
            else tree[x].son1 = i;
        }
        else
        {
            if(tree[x].son2)
            {
                int t = tree[x].son2;
                tree[x].son2 = i;
                tree[i].son2 = t;
            }
            else tree[x].son2 = i;
        }
    }
    cin >> m;
    for(int i = 1; i <= m; i++)
    {
        int x = read();
        vis[x] = 1;
    }
    dfs(1);
    return 0;
}

转载于:https://www.cnblogs.com/BigYellowDog/p/11182270.html

你可能感兴趣的:(洛谷 P1160 队列安排)