您的位置:首页 > 理论基础 > 计算机网络

ACM学习历程—NPU 2015年陕西省程序设计竞赛网络预赛(正式赛)A题 小女警的异世界之战(dfs && 分治)

2015-05-16 19:57 232 查看

Description

这一天,小女警花花,泡泡和毛毛来到终极Boss"Him"所在的异世界并准备与其决一死战,却被困在了他的城堡里。她们发现异世界是一个巨大的城堡。城堡由一个个大小不同的房间组成,房间有着以下的规则:

每个房间有且仅有一扇黄门,此外至多有一扇红门和一扇绿门:黄色代表通向更大的房间,绿色和红色代表通向更小的房间。很显然,如果你打开了一扇红/绿色的门,你会发现门的背面是黄色的,反之同理。

红色和绿色的门都是可以随意打开的,然而黄色的门要等到该房间其他门均被打开过,且该房间怪物已经被杀死时才能被打开。在成功穿过黄门后,这扇门就会消失。

每个房间都会有一个怪物,小女警可自由挑选打败怪物的时机而不影响其打开该房间的红/绿门。

三位小女警的起点就是一间较为特殊的房间,这个房间与正常房间的区别是黄门是特制的。为了解锁这个房间的特殊黄门,三位小女警必须分别依次探索这个房间的其他门,而每个小女警在探索时,怪物与门的状态都会重置。三位小女警的探索方式有着巨大的差别:

花花对红色有着狂热的痴迷,因此当她看见红门时,会暂时无视怪物而立刻冲进去,但是当所在房间没有红门时,她会恢复理智并优先将所在房间的怪物杀死,然后进入绿门(如果有的话)来解锁黄门。

泡泡有强烈的强迫症而且讨厌绿色,当她看到怪物时一定会将其杀死,然后她会优先开启红门,不得已时她才会进入绿门来解锁黄门。

毛毛有拖延症,因此她会优先去开她喜爱的红色的门,随后去开绿色的门,当其所在房间没有门可开时,她才会通过杀死怪物的方式解锁黄门并回去。

每个房间的怪物都有独一无二的名字,当小女警杀死怪物时,怪物的名字会按顺序被记录在日志上,现在花花和泡泡已经按规则探索过了这个城堡,并回到了出发点,毛毛借来了她们的日志以便预测她将会碰到的怪物的顺序,你能帮助她完成这个任务吗?

Input

数据有多组,每组数据以一个数字n(1<=n<=100)为开始,代表有n条记录,

接下来的两行分别是花花和泡泡的日志,分别包含了n个怪物的名字,用空格隔开。

n==0时,输入结束。

Output

输出一行毛毛的日志,怪物名字之间用空格隔开。

Sample Input

5
skeleton zombie spider bat witch
bat zombie skeleton spider witch
0


Sample Output

skeleton spider zombie witch bat


题目大意就是告诉你树的中序遍历和先序遍历,输出树的后序遍历。

从先序遍历下手,首先在第二组字符串里最先出现的一定是根节点,然后出现的是左子树的根节点(如果存在的话),依此递归定义。

然后再看第一个字符串,出现在根节点左侧的所有节点一定是左子树的所有节点,出现在右侧的一定是右子树的所有节点。然后看左侧部分,出现在左子树根节点左侧的一定是左子树的左子树的所有节点,依此递归定义。

然后就可以考虑分治了:

先从第二个字符串取出第一个,一定是根,然后在第一个字符串中找出这个节点(此处采用了map进行映射),(1)然后先对左侧进行分治:从第二个字符串取出第二个,同理找出左侧中这个节点,先对左侧的左半部分分治,然后对右半部份分治。(2)然后对右侧进行同样的分治。。。依此递归。树便建成。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <string>

using namespace std;

struct node
{
char val[50];
node *left, *right;
};

int n;
char str1[105][50], str2[105][50];
map <string, int> Hash;
bool flag;

void Input()
{
Hash.clear();
for (int i = 0; i < n; ++i)
{
scanf("%s", str1[i]);
Hash[str1[i]] = i;
}
for (int i = 0; i < n; ++i)
scanf("%s", str2[i]);
}

node *Build(int &state, int from, int to)
{
if (state >= n-1 || from > to)
return NULL;
state++;
if (from == to)
{
node *p = (node *)malloc(sizeof(node));
strcpy(p->val, str2[state]);
p->left = NULL;
p->right = NULL;
return p;
}

int k = Hash[str2[state]];
node *now = (node *)malloc(sizeof(node));
strcpy(now->val, str2[state]);
now->left = Build(state, from, k-1);
now->right = Build(state, k+1, to);
return now;
}

void Dfs(node *k)
{
if (k->left != NULL)
Dfs(k->left);
if (k->right != NULL)
Dfs(k->right);
if (flag)
printf(" ");
printf("%s", k->val);
flag = true;
}

void Work()
{
node *head;
int state = -1;
head = Build(state, 0, n-1);
flag = false;
Dfs(head);
printf("\n");
}

int main()
{
//freopen("test.in", "r", stdin);
while (scanf("%d", &n) != EOF && n)
{
Input();
Work();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐