CCF CSP认证 201809-3 元素选择器 (模拟) (100分)

 

 

 

 

 

思路:对文档建树,每个结点记录tag和id,然后每次选择在子树中查询即可

注意标签不区分大小写,样例中没有体现,不细心的话这里会被坑

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=1000+10,inf=0x3f3f3f3f;
 5 struct E {int v,nxt;} e[N];
 6 int n,m,hd[N],ne,dep[N],sta[N],U[N],tp;
 7 string tag[N],id[N];
 8 void link(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;}
 9 char buf[N];
10 void select(vector<int>& vec,int u,int mode,int type,string s) {
11     if((type==1&&tag[u]==s)||(type==2&&id[u]==s)) {
12         vec.push_back(u);
13         if(mode==1)return;
14     }
15     for(int i=hd[u]; ~i; i=e[i].nxt)select(vec,e[i].v,mode,type,s);
16 }
17 vector<int> select(vector<int> vec,int mode,int type,string s) {
18     vector<int> ret;
19     for(int u:vec)for(int i=hd[u]; ~i; i=e[i].nxt)select(ret,e[i].v,mode,type,s);
20     return ret;
21 }
22 vector<string> split(string S,char C) {
23     vector<string> vec;
24     string s;
25     for(char c:S) {
26         if(c!=C)s.push_back(c);
27         else vec.push_back(s),s.clear();
28     }
29     vec.push_back(s),s.clear();
30     return vec;
31 }
32 
33 int main() {
34     memset(hd,-1,sizeof hd),ne=0;
35     scanf("%d%d",&n,&m);
36     dep[n+1]=0,U[0]=n+1,sta[tp=0]=n+1;
37     for(int u=1; u<=n; ++u) {
38         scanf(" %[^\n]",buf);
39         string s=buf;
40         int t=s.rfind('.');
41         s=s.substr(t+1);
42         t=(t+1)/2+1;
43         dep[u]=t;
44         if(t==dep[sta[tp]]-2)tp-=2;
45         else if(t==dep[sta[tp]])tp-=1;
46         int f=sta[tp];
47         link(f,u);
48         sta[++tp]=u;
49         t=s.rfind(' ');
50         if(~t)tag[u]=s.substr(0,t),id[u]=s.substr(t+2);
51         else tag[u]=s,id[u]="";
52         for(char& c:tag[u])c=tolower(c);
53     }
54     while(m--) {
55         scanf(" %[^\n]",buf);
56         string s=buf;
57         vector<string> vec=split(s,' ');
58         vector<int> vv;
59         vv.push_back(n+1);
60         for(int i=0; i<vec.size(); ++i) {
61             int f=(i==vec.size()-1);
62             string s=vec[i];
63             if(s[0]=='#') {
64                 s=s.substr(1);
65                 vv=select(vv,f+1,2,s);
66             } else {
67                 for(char& c:s)c=tolower(c);
68                 vv=select(vv,f+1,1,s);
69             }
70         }
71         sort(vv.begin(),vv.end());
72         printf("%d",vv.size());
73         for(int x:vv)printf(" %d",x);
74         puts("");
75     }
76     return 0;
77 }

 样例

 1 11 5
 2 html
 3 ..head
 4 ....title
 5 ..body
 6 ....h1
 7 ....p #subtitle
 8 ....div #main
 9 ......h2
10 ......p #one
11 ......div
12 ........p #two
13 p
14 #subtitle
15 body #subtitle
16 div p
17 div div p

 

posted @ 2020-09-03 16:55  jrltx  阅读(192)  评论(0编辑  收藏  举报