前情提要:學長們都去牡丹江當炮灰了,我們隊只能做同步賽
決定開敲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;
}