思路参考:传送门
唯一遇到的坑是选择器也是可以重复出现在一条查询里的,而不是只能出现在最后。
#include<bits/stdc++.h>
using namespace std;
vector<string> res;//保存祖先
vector<string> qus;//保存查询
vector<int>ans;//保存答案
struct Node{
string table;
string id;
int level;
}e[105];
void toLower(string &str){
for(int i=0;i<str.size();i++){
if(isalpha(str[i]))str[i]=tolower(str[i]);
}
}
void split(string &str,int x){
int flag=0,s1=0,s2=0,sj=0;
string table,id;
for(int i=0;i<str.size();i++){
if(str[i]=='.')sj++;
if(str[i]!='.'&&flag==0){flag=1;s1=i;}
if(str[i]==' '&&flag==1){s2=i+1;flag=2;break;}
}
if(flag!=2){
table=str.substr(s1);
toLower(table);
e[x].table=table;
e[x].level=sj/2;
}
else if(flag==2){
table=str.substr(s1,s2-s1-1);
toLower(table);
id=str.substr(s2);
e[x].table=table;
e[x].id=id;
e[x].level=sj/2;
}
}
bool isMatch(int x){
int t=e[x].level,qq=qus.size()-2;
for(int j=x-1;j>=0;j--){
if(e[j].level==t-1){
if(qus[qq][0]!='#'&&qus[qq]==e[j].table){qq--;}
else if(qus[qq][0]=='#'&&qus[qq]==e[j].id){qq--;}
t=e[j].level;
if(qq<0)return 1;
}
}
return 0;
}
int main(){
#ifdef LOCAL
freopen("kk.txt","r",stdin);
#endif
int n,m;
string line;
cin>>n>>m;
getchar();
for(int i=0;i<n;i++){
getline(cin,line);
split(line,i);
}
for(int i=0;i<m;i++){
getline(cin,line);
stringstream ss;ss<<line;
string t;
while(ss>>t){
if(t[0]!='#')toLower(t);
qus.push_back(t);
}
int qsize=qus.size();
for(int j=0;j<n;j++){
if(qus[qsize-1][0]=='#'&&qus[qsize-1]==e[j].id
||qus[qsize-1][0]!='#'&&qus[qsize-1]==e[j].table){
if(qsize==1)ans.push_back(j+1);
else if(isMatch(j))ans.push_back(j+1);
}
}
cout<<ans.size();
for(int i=0;i<ans.size();i++){
cout<<" "<<ans[i];
}
cout<<endl;
res.clear();
ans.clear();
qus.clear();
}
return 0;
}