[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++]='\0';
    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;
}


阅读更多

没有更多推荐了,返回首页