hdu 5444 长春区域赛网络赛 1008 Elven Postman(模拟)

题目链接:

hdu 5444


题目大意:

给出一个序列,这个序列的第一个点是树的根节点,每次操作从当前点走到当前最靠右的每走过的点(点的序号越小越靠右),问将物品从根送到某个点的行进路线.


题目分析:

  • 个人认为难在题意。。。
  • 构造出这个树之后,直接从目的地走回根节点就可以得到要求的路径。
  • 然后如何构造呢?我们可以知道每次要到达的目的地就是当前位置后面的最小的点,然后每次我们从根节点出发,判断下一个序列中的点与当前在树上的位置上的数的大小关系,然后选择路径,直到找到最小的数,再重复这一操作即可。

AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int maxn = 1100;
struct tree{
    int v, l, r, f;
    tree(){}
    tree(int v, int l, int r, int f):v(v), l(l), r(r), f(f){}
} t[maxn<<2];
int T, n;
int pt, sz;
int st[maxn];
int a[maxn];
int ps[maxn];
bool v[maxn];

void work(int x){
    int pos = 0, ed = ps[x];
    while(1){
        if (pt > ed) break;
        v[a[pt]] = true;
        if (t[pos].v > a[pt]){
            if (t[pos].r == -1){
                st[a[pt]] = sz;
                t[sz] = tree(a[pt++], -1, -1, pos);
                t[pos].r = sz;
                pos = sz++;
            }
            else pos = t[pos].r;
        }
        else{
            if (t[pos].l == -1){
                st[a[pt]] = sz;
                t[sz] = tree(a[pt++], -1, -1, pos);
                t[pos].l = sz;
                pos = sz++;
            }
            else pos = t[pos].l;
        }
    }
}
char s[1100];
void output(int x){
    int len = 0, px;
    while(1){
        px = x;
        x = t[x].f;    
        if (x == -1) break;
        if (t[x].l == px) s[len++] = 'W';
        else s[len++] = 'E';
    }
    for (int i = 0, j = len-1; i < j; i++, j--)
        swap(s[i], s[j]);
    s[len] = 0;
    printf("%s\n", s);
}
int main()
{
    scanf("%d", &T);
    while(T--){
        scanf("%d", &n);
        for (int i = 0; i < n; i++){
            v[i+1] = false;
            scanf("%d", &a[i]);
            ps[a[i]] = i;
        }
        sz = 0, pt = 1;
        t[sz++] = tree(a[0], -1, -1, -1);
        v[a[0]] = true;
        for (int i = 1; i <= n; i++)
            if (!v[i]){ work(i); }
        int q, qq;
        scanf("%d", &q);
        for (int i = 0; i < q; i++){
            scanf("%d", &qq);
            output(st[qq]);
        }
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值