树 List Leaves 【用数组模拟了树状结构建树+搜索叶子节点+按照特殊规律输出每个叶子节点】

Given a tree, you are supposed to list all the leaves in the order of top down, and left to right.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤10) which is the total number of nodes in the tree -- and hence the nodes are numbered from 0 to N−1. Then N lines follow, each corresponds to a node, and gives the indices of the left and right children of the node. If the child does not exist, a "-" will be put at the position. Any pair of children are separated by a space.

Output Specification:

For each test case, print in one line all the leaves‘ indices in the order of top down, and left to right. There must be exactly one space between any adjacent numbers, and no extra space at the end of the line.

Sample Input:

8
1 -
- -
0 -
2 7
- -
- -
5 -
4 6

Sample Output:

4 1 5
分析:数据量很小,怎么写都过啊。于是我用结构体数组来模拟建立树状结构。然后找到每个叶子节点,但输出有要求。先输出深度小的节点,深度相同的叶子节点先输出靠左的叶子节点,再输出靠右的叶子节点。样例建树后的样子
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <queue>
#include <algorithm>

using namespace std;

struct node
{
    int ll;
    int rr;
    int data;
    int dep;
    int dfn;
}q[20];

struct N
{
    int num;
    int dep;
    int dfn;
    bool operator<(const N &dd)const{
        if(dep==dd.dep)
            return dd.dfn<dfn;
        else
            return dd.dep<dep;
    }
};

int cnt;
void dfs_leaf(int root, int deep)
{
    if(q[root].ll==-1 && q[root].rr==-1)
        return;
    if(q[root].ll!=-1){
        int v=q[root].ll;
        q[v].dep=deep+1;
        q[v].dfn=cnt++;
        dfs_leaf(v, deep+1);
    }
    if(q[root].rr!=-1){
        int v=q[root].rr;
        q[v].dep=deep+1;
        q[v].dfn=cnt++;
        dfs_leaf(v, deep+1);
    }
}

int main()
{
    int n; scanf("%d%*c", &n);
    int i, j, k;
    char a[5], b[5];
    for(i=0; i<n; i++){
        scanf("%s %s", a, b);
        if(a[0]==‘-‘){
            q[i].ll=-1;
        }else{
            q[i].ll=a[0]-48;
        }

        if(b[0]==‘-‘){
            q[i].rr=-1;
        }else{
            q[i].rr=b[0]-48;
        }//模拟每一个树节点
    }//建树完成
    bool f[20];//标记每一个节点是不是儿子
    memset(f, false, sizeof(f));
    for(i=0; i<n; i++){
        if(q[i].ll!=-1){
            f[q[i].ll]=true;
        }
        if(q[i].rr!=-1){
            f[q[i].rr]=true;
        }
    }
    int root;
    for(i=0; i<n; i++){
        if(f[i]==false){
            root=i; break;
        }
    }
   //printf("root = %d\n", root);

    cnt=1;
    q[root].dfn=0; q[root].dep=0;
    dfs_leaf(root, 0);

    priority_queue<N>que;
    N cur;
    for(i=0; i<n; i++){
        if(q[i].ll==-1&&q[i].rr==-1){
            cur.num=i;
            cur.dep=q[i].dep;
            cur.dfn=q[i].dfn;
            que.push(cur);
            //printf("%d节点:深度%d 次序%d\n", i, q[i].dep, q[i].dfn);
        }
    }

    bool z=false;
    while(!que.empty()){
        if(z==false){
            printf("%d", que.top().num); z=true; que.pop();
        }
        else{
            printf(" %d", que.top().num); que.pop();
        }
    }printf("\n");
    return 0;
}
 
时间: 2024-10-09 08:23:37

树 List Leaves 【用数组模拟了树状结构建树+搜索叶子节点+按照特殊规律输出每个叶子节点】的相关文章

Hdu 3887树状数组+模拟栈

题目链接 Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1757    Accepted Submission(s): 582 Problem Description You are given a tree, it’s root is p, and the node is numbered fr

Codeforces 216D Spider&#39;s Web 树状数组+模拟

题目链接:http://codeforces.com/problemset/problem/216/D 题意: 对于一个梯形区域,如果梯形左边的点数!=梯形右边的点数,那么这个梯形为红色,否则为绿色, 问: 给定的蜘蛛网中有多少个红色. 2个树状数组维护2个线段.然后暴力模拟一下,因为点数很多但需要用到的线段树只有3条,所以类似滚动数组的思想优化内存. #include<stdio.h> #include<iostream> #include<string.h> #in

Codeforces 12D Ball 树状数组模拟3个元素的排序

题目链接:点击打开链接 #include<stdio.h> #include<iostream> #include<string.h> #include<set> #include<vector> #include<map> #include<math.h> #include<queue> #include<string> #include<stdlib.h> #include<a

Uva - 1513 Moive collection ( 模拟栈 + 树状数组基本操作 )

Uva - 1513 Moive collection ( 模拟栈 + 树状数组基本操作 ) 题意: 一个书架,原来所有的书都是按顺序摆好的,书的编号从1开始到n 操作: 取出一本书,统计在这本书之前有多少本书,统计完之后,将这本书放在书架的第一位. 如:  1 2 3 4 5取4   4 1 2 3 5 (取之前,有3本书在4前面,取完后,将4放在栈顶)取4   4 1 2 3 5 (取之前,有0本书在4前面,取完后,将4放在栈顶)取2   2 4 1 3 5 (取之前,有2本书在2前面,取完

HDU 4825 Xor Sum(二进制的字典树,数组模拟)

题目 //居然可以用字典树...//用cin,cout等输入输出会超时 //这是从别处复制来的 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int node[3011111][2]; int tag,m,n,cas=0,T; long long one[64],allone,tmp; //0/1树的加数据操作,增加一个32的数 //其中如果当前位是0,则加左儿子,

树状数组和线段树

一.树状数组 在解题过程中,我们有时需要维护一个数组的前缀和 S[i]=A[1]+A[2]+...+A[i] .但是不难发现,如果我们修改了任意一个 A[i],S[i] . S[i+1]...S[n] 都会发生变化.可以说,每次修改 A[i] 后,调整前缀和 S[] 在最坏情况下会需要 O(n) 的时间.当 n 非常大时,程序会运行得非常缓慢.因此,这里我们引入"树状数组",它的修改与求和都是 O(logn) 的,效率非常高. 实现: 对于正整数x,定义lowbit(x)为x的二进制表

2016&quot;百度之星&quot; - 资格赛(Astar Round1)-(模拟+线段树+乘法逆元)

Problem A Accepts: 1351 Submissions: 9951 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 度熊手上有一本字典存储了大量的单词,有一次,他把所有单词组成了一个很长很长的字符串.现在麻烦来了,他忘记了原来的字符串都是什么,神奇的是他竟然记得原来那些字符串的哈希值.一个字符串的哈希值,由以下公式计算得到: H

浅谈二维中的树状数组与线段树

一般来说,树状数组可以实现的东西线段树均可胜任,实际应用中也是如此.但是在二维中,线段树的操作变得太过复杂,更新子矩阵时第一维的lazy标记更是麻烦到不行. 但是树状数组在某些询问中又无法胜任,如最值等不符合区间减法的询问.此时就需要根据线段树与树状数组的优缺点来选择了. 做一下基本操作的对比,如下图. 因为线段树为自上向下更新,从而可以使用lazy标记使得矩阵的更新变的高校起来,几个不足就是代码长,代码长和代码长. 对于将将矩阵内元素变为某个值,因为树状数组自下向上更新,且要满足区间加法等限制

poj 3253 Fence Repair(模拟huffman树 + 优先队列)

题意:如果要切断一个长度为a的木条需要花费代价a, 问要切出要求的n个木条所需的最小代价. 思路:模拟huffman树,每次选取最小的两个数加入结果,再将这两个数的和加入队列. 注意priority_queue的用法,原型: 1 priority_queue<Type> q; 2 priority_queue<Type,deque<Type>,Comp> q; 其中Type是类型,Comp是比较结构体,比较函数是它的括号重载,比如对int型从小到大排序的Comp结构体如