CCF CSP認證 201809-3 元素選擇器 (模擬)
阿新 • • 發佈:2020-09-03
思路:對文件建樹,每個結點記錄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(intu,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) { 23vector<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 }