HDU 4041 Eliminate Witches! (栈的模拟)

Eliminate Witches!

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1234    Accepted Submission(s): 461

Problem Description

Kaname Madoka is a Magical Girl(Mahou Shoujo/Puella Magi). The duty of a Magical Girl is to eliminate Witches(Majo). Though sounds horrific, it is not a hard job for her as a powerful magical girl.

One day Madoka is eliminating Witches as usual. This time she is facing a maze full of Witches. The maze consists of rooms, each lives exactly one Witch. And there is exactly one path from one room to another. So you see, the maze can be represented as a tree,
with rooms regarded as nodes on the tree.

Madoka eliminates Witches according to the following rules:

1. At first, Madoka enters the root node room of the maze.

2. If the room Madoka enters lives a Witch, Madoka will eliminate it at once, and the Witch disappear.

3. If the room has child node rooms with Witches, Madoka will choose the leftmost one and enter it.

4. Madoka won‘t go back to the parent node room of a room X until Witches living in child node rooms of X are all eliminated.

See the figure below for details about a sample maze. The numbers inside nodes indicate the order of elimination of the corresponding Witches, the strings below nodes are names of Witches, and the arrow shows the tracks Madoka travels:

After finishes her task, Madoka just make a brief log like this:

"walpurgis(charlotte(patricia,gertrud),elly,gisela)"

which represents the tree-like maze identifying rooms by the names of Witches living in them.

Akemi Homura, a classmate of Madoka, also a Magical Girl, is a mad fan of her. She wants to take detailed notes of everything Madoka do! Apparently the log Madoka made is hard to read, so Homura decide to make a new one of her own.

The new log should contain the following information:

1. The number of rooms of the maze

2. Names of Witches in all rooms.

3. The tracks Madoka travels. (represented by the number identifying the node)

So the new log should be like this:

6

walpurgis

charlotte

patricia

gertrud

elly

gisela

1 2

2 3

3 2

2 4

4 2

2 1

1 5

5 1

1 6

6 1

However, the maze may be very large, so Homura nees a program to help her.

Input

The first line contains an integer T(T<=20), indicating the number of test cases.

For each case there is only one string on a line, Madoka‘s log.

It is guaranteed that the maze consists of at most 50000 rooms, and the names of Witches is a string consists of at most 10 lowercase characters, while the string of Madoka‘s log consists of at most 1000000 characters, which are lowercase characters, ‘(‘, ‘)‘
or ‘,‘.

Output

For each case, you should output the detailed log.

The first line an integer N, the number of rooms of the maze.

The following N lines, each line a string, the name of the Witches, in the order of elimination.

The following 2(N-1) lines, each line two integers, the number of two nodes indicating the path Madoka passes.

Output a blank line after each case.

Sample Input

3
walpurgis(charlotte(patricia,gertrud),elly,gisela)
wuzetian
nanoha(fate(hayate)) 

Sample Output

6
walpurgis
charlotte
patricia
gertrud
elly
gisela
1 2
2 3
3 2
2 4
4 2
2 1
1 5
5 1
1 6
6 1 

1
wuzetian 

3
nanoha
fate
hayate
1 2
2 3
3 2
2 1

Source

The 36th
ACM/ICPC Asia Regional Beijing Site —— Online Contest

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4041

题目大意:用单词,括号和逗号输入一棵树,逗号并列的是兄弟,a(...),括号里的都是a的孩子,求按输入的单词的顺序遍历树的路径

题目分析:看样例可以发现路径就是树上结点进栈出栈的过程,可以用栈来模拟

‘(‘ :表示遇到子结点,子结点进栈,输出父亲 -> 儿子

‘,‘ :表示遇到兄弟,先回到父亲,当前这个儿子出栈,输出儿子 -> 父亲,兄弟进栈,输出父亲 -> 兄弟

‘)‘ :表示访问完一层的兄弟,最后一个兄弟出栈,输出最后一个兄弟 -> 父亲

注意这题要用c++交,用g++ T了10几次后卡A了一次,c++交124ms,这题可以有个优化,遍历字符串的时候可以在输入时预处理,只提取出‘(‘ ‘)‘ ‘,‘这些有效字符

#include <cstdio>
#include <cstring>
#include <stack>
using namespace std;
int const MAX = 1e6 + 5;

char s[MAX], s2[MAX];
char node[50005][11];

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        stack <int> st;
        memset(node, 0, sizeof(node));
        scanf("%s", s);
        int cnt = 1, len = 0, cnt2 = 0;
        for(int i = 0; s[i] != '\0'; i++)
        {
            if(s[i] >= 'a' && s[i] <= 'z')
                node[cnt][len++] = s[i];
            if((s[i] == '(' || s[i] == ')' || s[i] == ',') && (s[i - 1] >= 'a' && s[i - 1] <= 'z'))
            {
                len = 0;
                cnt++;
            }
            if(s[i] == '(' || s[i] == ')' || s[i] == ',')
                s2[cnt2++] = s[i];
        }
        if(cnt == 1)
            cnt++;
        printf("%d\n", cnt - 1);
        for(int i = 1; i < cnt; i++)
            printf("%s\n", node[i]);
        cnt = 1;
        st.push(1);
        for(int i = 0; i < cnt2; i++)
        {
            if(s2[i] == '(')
            {
                int tmp = st.top();
                st.push(++cnt);
                printf("%d %d\n", tmp, st.top());
            }
            else if(s2[i] == ',')
            {
                int tmp = st.top();
                st.pop();
                printf("%d %d\n", tmp, st.top());
                tmp = st.top();
                st.push(++cnt);
                printf("%d %d\n", tmp, st.top());
            }
            else if(s2[i] == ')')
            {
                int tmp = st.top();
                st.pop();
                printf("%d %d\n", tmp, st.top());
            }
        }
        printf("\n");
    }
}
时间: 2024-10-09 12:29:45

HDU 4041 Eliminate Witches! (栈的模拟)的相关文章

HDU 4041 Eliminate Witches! --模拟

题意: 给一个字符串,表示一颗树,要求你把它整理出来,节点从1开始编号,还要输出树边. 解法: 模拟即可.因为由括号,所以可以递归地求,用map存对应关系,np存ind->name的映射,每进入一层括号,使father = now, 遇到右括号')',则father = fa[father],用vector存每个节点的子节点,然后最后dfs输出即可. 代码: #include <iostream> #include <cstdio> #include <cstring&

HDU ACM 4041 Eliminate Witches! 队列和栈模拟DFS

分析:直接模拟即可,这里用队列记录访问过的点,栈记录父节点.另外要注意的是在strlen(str)计算字符串的时候要预先计算出来保存在变量中,for直接用,如果for循环直接调用strlen,那么每次都会重新计算,该題字符串的数据量很大,就会存在大量的无用计算,还导致了一次TLE,唉!以前没注意到这里. #include<iostream> #include<vector> #include<queue> #include<stack> using name

HDU 4043 Eliminate Witches! (求概率推公式 + 大数)

FXTZ II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 525    Accepted Submission(s): 276 Problem Description Cirno is playing a fighting game called "FXTZ" with Sanae. Sanae is a ChuShou

HDU1022 Train Problem I 栈的模拟

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1042 栈的模拟,题目大意是已知元素次序, 判断出栈次序是否合理. 需要考虑到各种情况, 分类处理. 常见错误:使用前未清空栈 使用STL思路较为清晰 代码附上, 欢迎各位大神指点~~ #include <cstdio> #include <stack> #include <iostream> #include <vector> using namespace s

hdu 5640 King&#39;s Cake(模拟)

Problem Description It is the king's birthday before the military parade . The ministers prepared a rectangle cake of size n×m(1≤n,m≤10000) . The king plans to cut the cake himself. But he has a strange habit of cutting cakes. Each time, he will cut

hdu 4930 Fighting the Landlords (模拟)

Fighting the Landlords Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 160    Accepted Submission(s): 52 Problem Description Fighting the Landlords is a card game which has been a heat for ye

hdu 4891 The Great Pan (模拟)

为什么要开__int64 巨巨在哪~ # include <stdio.h> # include <algorithm> # include <string.h> using namespace std; int main () { __int64 count; int i,len,cot,cot1,j,flag,n; char a[1001][1030]; while(~scanf("%d",&n)) { getchar(); flag=0

HDU 4930 Fighting the Landlords(模拟)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4930 解题报告:斗地主,加了一个四张可以带两张不一样的牌,也可以带一对,判断打出一手牌之后,如果对手没有能够大过你的牌就输出Yes,或者如果你把手上的牌一次性打完也输出Yes,否则输出No,代码有280多行,表示光是敲代码就花了一个多小时,手速还是太慢. 1.首先判断手上的牌能不能一次打完 如果一次性打不完: 2.首先判断对方有没有一对王,有就输出No 3.判断对手有没有四张的牌,如果有,再判断自己

2014多校第三场1005 || HDU 4891 The Great Pan(模拟)

题目链接 题意 : 给你n行字符串,问你有多少种理解方式.有两大类的理解 (1){A|B|C|D|...}代表着理解方式可以是A,可以是B或C或者D. (2)$blah blah$,在$$这两个符号中间,如果是不连续的空格的那个位置就有2种理解方式,可以理解为没有空格也可以理解为有空格.如果有连续N个空格的位置,那里就有N+1种理解方式. 最后所有的理解方式相乘,数据保证$一定与$匹配,{一定与匹配},不会有任何嵌套,类似{$$}或者{{}}或者${}$这种情况都不会出现,也不会有{$}这种情况