zoukankan      html  css  js  c++  java
  • [2014 Regional]牡丹江 H Hierarchical Notation 做题记录

    主妇:老年人谁是炮灰牡丹江,我们的团队只是做同步大赛

    他决定开爆震H什么时候,A 5min 1Y。I在该限制后,纠结了很久30min+ 1Y,神继续承担各种位置卡D在,hpp见B我认为这是非常熟悉的研究ing

    告诉我,然后看积分榜,并且K和H。

    K想叫队友一起想一下(毕竟过的人非常多了),可是不好意思叫。然后看H,非常有一种XML那种树形数据描写叙述结构的味道。可是语法简单太多了(好像不应该扯XML的……)

    感觉上是一个中难偏简单的模拟,于是就開始考虑怎么实现好了。

    估算一下字符串长度,10000冒号*2个描写叙述字符串*每一个描写叙述串22个字符。再满打满算算上10000对花括号、10000个逗号,500000大的char[]够了吧?

    然后详细处理的时候,我的第一反应是,写个kmp,然后分段在我所给定的区间找,找到输出相应的value,找不到输出Error

    熊神听到我的想法一票否决,500000*1000怎么算都认为挺作死的……

    熊神提出一种想法。用map呗。假设value还是EON就指向还有一个map。


    好吧,那继续想怎么写程序(这个时候熊神找到了正确的D的姿势,交上去1Y)。想了想。结构体我又来了……

    整体思路:一对Key-Value对为一个node。node里面记录value在原串里面的開始和结束位置(不要复制字符串,非常糟糕的情况下会爆内存的),还要区分两种类型,一种是直接文本的value。还有一种是一个EON。那要指向一个map 。

    花括号嵌套的时候,用手工栈记录如今是在往哪个map里增加Key-Value对。


    然后就啪嗒啪嗒啪嗒的敲啊敲啊敲啊……

    第一次交上去RE,细致一看。map没初始化好。改了再交,还是RE

    好吧,于是開始了造数据——毕竟sample弱啊

    {"hm":"Edward","stu":{"stu01":"Alice","stu02":"Bob"},"stu01":"aaa"}
    5
    "hm"
    "stu"
    "stu"."stu01"
    "stu01"
    "students"
    {"hm":"Edward","stu":{"stus":{"stu01":"Alice","stu02":"Bob"}},"name":"school"}
    5
    "hm"
    "stu"
    "stu"."stu01"
    "stu"."stus"
    "name"

    然后果然压中了……

    }},这里的处理没处理好,改一下,然后就3Y了


    只是老实说。我写了137行的代码也是醉了……

    熊神表示,实际赛场上绝对是他去写递归下降了……

    下面是代码:


    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <math.h>
    #include <iostream>
    #include <map>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    char str[500005];
    char query[500005];
    map<string,int> ms[10005];
    char tmp[2000];
    
    struct Node
    {
        int type;
        int sp,ep;
        int mapid;
        void showme()
        {
            for(int i=sp;i<=ep;i++)
                printf("%c",str[i]);
            puts("");
        }
    }node[10005];
    
    int phrase(char *str,int &p)
    {
        int idx=0;
        do
        {
            tmp[idx++]=str[p];
            p++;
        }while(str[p]!='"');
        tmp[idx++]='"';
        tmp[idx++]='';
        p++;
        return idx;
    }
    
    int findbrac(int p)
    {
        int lbrac=0;
        for(int i=p;;i++)
        {
            if(str[i]=='{')
                lbrac++;
            else if(str[i]=='}')
                lbrac--;
            if(lbrac==0)
                return i;
        }
    }
    
    int stack[10005];
    
    int main()
    {
        int T;
        for(scanf("%d%*c",&T);T--;)
        {
            gets(str);
            for(int i=0;i<=10001;i++)
                ms[i].clear();
            int len=strlen(str),stop=0,mcnt=1;
            int ncnt=1,p=1;
            stack[0]=0;
            for(;p<len-1;p++)
            {
                if(str[p]==',')continue;
                if(str[p]=='}')
                {
                    stop--;
                    continue;
                }
                phrase(str,p);
                p++;
                if(str[p]=='"')
                {
                    node[ncnt].type=0;
                    node[ncnt].sp=p;
                    ms[stack[stop]][tmp]=ncnt;
                    phrase(str,p);
                    node[ncnt].ep=p-1;
                    ncnt++;
                }
                else
                {
                    node[ncnt].type=1;
                    node[ncnt].sp=p;
                    node[ncnt].ep=findbrac(p);
                    node[ncnt].mapid=mcnt++;
                    ms[stack[stop]][tmp]=ncnt;
                    stop++;
                    stack[stop]=node[ncnt].mapid;
                    ncnt++;
                }
                if(str[p]=='}')
                    stop--;
            }
            int Q;
            for(scanf("%d%*c",&Q);Q--;)
            {
                gets(query);
                int ctmap=0,p=0,len=strlen(query);
                for(;p<len;p++)
                {
                    phrase(query,p);
                    map<string,int>::iterator it=ms[ctmap].find(tmp);
                    if(it==ms[ctmap].end())
                    {
                        puts("Error!");
                        break;
                    }
                    int nid=it->second;
                    if(query[p]=='.'&&node[nid].type!=1)
                    {
                        puts("Error!");
                        break;
                    }
                    if(query[p]=='.')
                    {
                        ctmap=node[nid].mapid;
                    }
                    else
                    {
                        node[nid].showme();
                        break;
                    }
                }
            }
        }
        return 0;
    }
    


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    八、JVM视角浅理解并发和锁
    七、JVM类加载机制
    六、JVM命令和工具
    五、jvm垃圾回收3(几种垃圾收集器)
    四、JVM垃圾回收2(垃圾收集算法)
    jvm引用类型
    三、JVM垃圾回收1(如何寻找垃圾?)
    【原创】Android 对话框的使用
    【原创】CMD常用命令:解决实际问题
    【原创】开机出现grub rescue,修复办法
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4904098.html
Copyright © 2011-2022 走看看