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

    Description

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

    1. 每个房间有且仅有一扇黄门,此外至多有一扇红门和一扇绿门:黄色代表通向更大的房间,绿色和红色代表通向更小的房间。很显然,如果你打开了一扇红/绿色的门,你会发现门的背面是黄色的,反之同理。
    2. 红色和绿色的门都是可以随意打开的,然而黄色的门要等到该房间其他门均被打开过,且该房间怪物已经被杀死时才能被打开。在成功穿过黄门后,这扇门就会消失。
    3. 每个房间都会有一个怪物,小女警可自由挑选打败怪物的时机而不影响其打开该房间的红/绿门。

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

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

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

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

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

    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("
    ");
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        while (scanf("%d", &n) != EOF && n)
        {
            Input();
            Work();
        }
        return 0;
    }
    
  • 相关阅读:
    学会使用控件之comboxBox in asp.net 从简单开始(五)
    学会使用控件从简单开始(四)
    关于SQL计算差值的问题
    关于CSS3的一些代码
    显式实现的接口成员从简单开始(三)
    网页选项卡(TAB)今天晚上搞了一晚上这个
    关于页面刷新
    委托和匿名方法从简单开始(一)
    短信监听器
    android中handler处理message小例子
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4508522.html
Copyright © 2011-2022 走看看