HDU - 4041 ----Eliminate Witches!

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: 

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

 

 

题意:给你一串字符串,  每对“()”表示的是“(”之前节点的子树串;   如果用1——n表示节点出现的点,让你建完树以后,输出一遍建树的过程,也就是dfs一遍树就行;

 

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <map>

using namespace std;
typedef long long LL;
const int maxn =  1e5 + 5;

string s;   //输入的字符串
vector <int> v[maxn];  //建树
map<int,string> name;  //存放名字
int vid[maxn];    //为建完树后dfs标记
stack <int> ss;  //准备一个栈存放每个深入的fa节点  栈顶的位置永远是你dfs进去建树的最近的fa
int cnt;  //记录有几个点序号

void init()   //预处理
{
	for(int i = 0;i <= maxn;i++)	v[i].clear();
	while(!ss.empty()) ss.pop();
	name.clear();
	memset(vid, 0, sizeof(vid));
}

void solve()
{
	string t;
	int len = s.length();
	cnt = 0;
	for(int i = 0;i < len;i++){
		if(s[i] == '('){                  //遇到‘(’
			if(!t.empty())   //名字不为空
			{
				name[++cnt] = t;    //把名字统一按序号存在name
				if(!ss.empty())  v[ss.top()].push_back(cnt);    //在fa的这一行 也就是栈顶压入即将出现的点
				t.clear();  //清空分割名字的t数组
			}
			ss.push(cnt);   //推入一个心的即将出现的fa
		}
		else if(s[i] == ')'){    //栈顶fa节点的树建完了
			if(!t.empty()){
				name[++cnt] = t;   //记录name
				if(!ss.empty())  v[ss.top()].push_back(cnt);  //
				t.clear();
			}
			ss.pop();  //建完树推出栈顶
		}
		else if(s[i] == ','){   //栈顶点的下一个子节点
			if(!t.empty()){
				name[++cnt] = t;
				if(!ss.empty())  v[ss.top()].push_back(cnt);
				t.clear();
			}
		}
		else t += s[i]; //记录名字
	}
	if(!t.empty()){    //假如只有一个点的情况
		name[++cnt] = t;
	}
}
void dfs(int x)  //正常遍历树
{
	vid[x] = 1;
	for(int i = 0;i < v[x].size();i++)
	{
		int g = v[x][i];
		if(vid[g] == 0)
		{
			printf("%d %d\n",x, g);  //输出进去的位置
			dfs(g);
			printf("%d %d\n",g, x);  //反过来就是出来的位置
		}
	}
}

int main()
{
	int t ;
	scanf("%d",&t);   //t次样例
	while(t--)
	{
		init();  //每次预处理
		cin >> s;  
		solve();
		printf("%d\n",cnt);//先输出点数
		for(int i = 1;i <= cnt;i++) cout << name[i] << endl;//按点数输出名字
		dfs(1);    //遍历一遍树
		printf("\n");
	}
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值