树-物质分解记录

总时间限制: 60000ms

单个测试点时间限制: 6000ms

内存限制: 131064kB

描述

对 物质分解记录 的结构进行统计分析。
例如:
给出一份 物质分解记录。
Material_1
{
Material_2
{
Material_3
                Material_4
Material_5
                {
                Material_6
                Material_7
                }
                Material_8
}
Material_9
Material_10
}
Material_11
{
Material_l3
Material_7
Material_2
{
Material_3
                Material_4
Material_5
                {
             Material_6
             Material_7
                }
                Material_8
}
Material_13
}

上述记录的含义是,Material_1分解为 Material_2、Material_9和Material_10,Material_2又分解为Material_3、Material_4、Material_5和Material_8。以此类推,大括号外书写特定物质名称,括号内表示此特定物质分解出来的子物质名称,每个子物质还可再分解。

现输入一个物质名称R,要求输出所有和物质R在记录中属于同一层次且位置在R之后的物质名称。
比如R=“Material_1” ,则应该输出“Material_11”;
比如R=“Material_9” ,则应该输出“Material_10”
如果R在代码中出现了多次,则以其第一次出现为准,即仅输出与第一次出现的R属于同一层次且位置在R之后的语句内容。
比如R=“Material_2” ,则应该输出
        Material_9
Material_10

输入

输入包含多组数据。第一行是物质分解记录的份数,仅用一个整数表示。从第二行开始,每组数据包括 物质分解记录 和 所需查找的物质R 两部分,物质分解记录样式如描述中所示,R的内容和物质分解记录之间有一行空行,下一份记录与上一个R之间有两行空行。
若输入!则表示输入结束。
为简单起见,物质分解记录中每一行的内容为“{”或者“}”或者一个物质名称,不会有其他情况(比如空行)出现。同时每行文字前不会有任何缩进。物质名称是英文字母、数字和下划线组成的字符串。

输出

对每组数据输出一行,如果R在记录中找到,则输出所有与R在同一层次且位置在R之后的物质名称,名称之间无需添加空格,紧密连接即可;否则输出No。若R是其所在层次中最后一个物质,则输出"",即输出一个空字符。

样例输入

3
Material_1
{
Material_2
{
Material_3
Material_4
Material_5
{
Material_6
Material_7
}
Material_8
}
Material_9
Material_10
}

Material_2


Material_1
{
Material_2
{
Material_3
Material_4
Material_5
{
Material_6
Material_7
}
Material_8
}
Material_9
Material_10
}
Material_11
{
Material_3
Material_7
Material_2
{
Material_3
Material_4
Material_5
{
Material_6
Material_7
}
Material_8
}
Material_13
}

Material_2


Material_1
{
Material_2
{
Material_3
Material_4
Material_5
{
Material_6
Material_7
}
Material_8
}
Material_9
Material_10
}

Material_20


!

样例输出

Material_9Material_10
Material_9Material_10
No

提示

读入数据时,需采用如下方式进行读取。
例:若要读取一行输入内容,则
cin.getline(line, lineSize, '\n');
sscanf(line, "%s", tmp);

其中line和tmp为数组指针,类型为char* ,linesize为line所指向的数组的规模,为int型。
所需读取的内容最终是存储在tmp数组中。之后如需对读取的内容进行操作,就对tmp进行操作即可,读到空行时tmp长度即为0。

采用其他方法读取可能会出现WA以及RE,TLE。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;

char line[1005];

struct node {
    string name;
    node *left_child, *right_sibling;
    node(string name_) : name(name_), left_child(NULL), right_sibling(NULL) {}
};

void read_line()
{
    static char tmp[1005];
    cin.getline(tmp, 1005);
    sscanf(tmp, "%s", line);
    if (tmp[0] == 0)
        line[0] = 0;
}

void delete_tree(node *root)
{
    if (root->left_child)
        delete_tree(root->left_child);
    if (root->right_sibling)
        delete_tree(root->right_sibling);
    delete root;
}

bool isstop = 0;
void build_tree(node *root)
{
    node *cur = root;
    while (true) {
        read_line();
        if (strcmp(line, "") == 0 || strcmp(line, "!") == 0) {
            isstop = 1;
            return;
        }
        if (strcmp(line, "}") == 0)
            return;
        else if (strcmp(line, "{") == 0) {
            build_tree(cur);
            if (isstop)
                return;
        }
        else {
            if (cur == root) {
                cur->left_child = new node(string(line));
                cur = cur->left_child;
            }
            else {
                cur->right_sibling = new node(string(line));
                cur = cur->right_sibling;
            }
        }
    }
}

node *find_node(node *root, string& s)
{
    node *cur = root->left_child;
    while (cur) {
        if (cur->name == s)
            return cur;
        node *rst = find_node(cur, s);
        if (rst)
            return rst;
        cur = cur->right_sibling;
    }
    return NULL;
}

void print_following_node(node *p)
{
    p = p->right_sibling;
    while (p) {
        printf("%s", p->name.c_str());
        p = p->right_sibling;
    }
    printf("\n");
}

int main()
{
    node *root;
    int n;
    cin >> n; getchar();
    for (int i = 0; i < n; ++i) {
        root = new node(string(""));
        isstop = 0;

        build_tree(root);

        read_line();
        string s = string(line);
        node *p = find_node(root, s);
        if (p) 
            print_following_node(p);
        else 
            printf("No\n");

        read_line();
        read_line();
        delete_tree(root);
    }
    system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/w112348/article/details/109406700