hdu5444(2015长春网络赛H题)

题意:

给出一棵树的描述,这棵树构造出来,满足从右到左数值递增,根在最下面,然后有一些询问x,我们要输出从根走到x的路径,w:向左、e:向右。


思路:

建树的时候,首先第一个点一定是根,然后比根小的建在根的右边,反之建在左边,就可以了。


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;

const int maxn = 1005 * 2 + 10;
int a[maxn];
int aa[maxn];

int le[maxn], ri[maxn];
int fa[maxn];
int ha[maxn];

int main() {
    int t, n;
    scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        memset(aa, 0, sizeof(aa));
        for(int i = 1; i <= n; i++) {
            scanf("%d",&a[i]);
        }
        for(int i = 1; i <= n; i++) {
            fa[i] = i;
        }
        int tot = 1;
        aa[tot++] = a[1];
        memset(le, 0, sizeof(le));
        memset(ri, 0, sizeof(ri));
        memset(ha, 0, sizeof(ha));
        for(int i = 2; i <= n; i++) {
            int rt = 1;
            while(1) {
                if(a[i] > aa[rt]) {
                    if(le[rt] == 0) {
                        le[rt] = tot++;
                        aa[le[rt]] = a[i];
                        fa[le[rt]] = rt;
                        ha[le[rt]] = 1;
                        break;
                    } else {
                        rt = le[rt];
                    }
                } else {
                    if(ri[rt] == 0) {
                        ri[rt] = tot++;
                        aa[ri[rt]] = a[i];
                        fa[ri[rt]] = rt;
                        break;
                    } else {
                        rt = ri[rt];
                    }
                }
            }
        }
        int m;
        int x;
        scanf("%d",&m);
        while(m--) {
            scanf("%d",&x);
            int hh = 1;
            int x_1 = n * 2 + 10;
            for(int i = 1; i <= x_1; i++) {
                if(aa[i] == x) {
                    hh = i;
                }
            }
            string s = "";
            while(hh != 1) {
                if(ha[hh] == 0) {
                    s += 'E';
                } else {
                    s += 'W';
                }
                hh = fa[hh];
            }
            int l = s.length();
            if(l == 0) {
                puts("");
                continue;
            }
            for(int i = l - 1; i >= 0; i--) {
                printf("%c",s[i]);
            } puts("");
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值