题目
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/4526ca1c4b29272852df2b90f37c8a7c.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5d24e4903193ff10a3ea5acb72739054.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/6931890a932acf313c21689552040b2f.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/3c60bb09120b006c5ae6ce50170012c1.png)
题解
1.本题模拟了css的dom树查找操作,但实际上并不需要建树(有点复杂),我们可以直接根据层级的深度来模拟树的层级关系
2.我们观察可以发现对于查找来说 如果我们匹配到最后一个标签(id)那么我们只要可以在他前面找到到达这个标签的路径就可以了(逆序找路层级(cnt)递减)
注意:仅仅对标签大小写不敏感但是对于id大小写敏感(不然只有90分)
c++代码:
#include<iostream>
#include<string>
#include<string.h>
#include<vector>
using namespace std;
const int N=105;
struct Node{
string lable,id;
int cnt;
}a[N];
string toLower(string str){
if(str[0] == '#') return str;
for(int i=0;i<str.length();i++){
if(str[i] >= 'A' && str[i] <= 'Z')
str[i] = str[i] - 'A' + 'a';
}
return str;
}
vector<string> query(0);
vector<int> ans(0);
bool search(Node a[],int &start,int &cnt,string s)
{
for(int i=start;i>=1;i--)
{
if(a[i].cnt<cnt)
{
cnt=a[i].cnt;
start=i;
if(s==a[i].lable||s==a[i].id) return true;
}
}
return false;
}
int main()
{
int n,m;
string s;
cin>>n>>m;
cin.ignore();
for(int i=1;i<=n;i++)
{
getline(cin,s);
a[i].cnt = 0;
a[i].id = "";
a[i].lable = "";
for(int j=0;j<s.length();j++){
if(s[j] == '.') a[i].cnt++;
else if(s[j] == ' ')
a[i].lable = toLower(s.substr(a[i].cnt,j-a[i].cnt));
else if(j+1 == s.length())
a[i].lable = toLower(s.substr(a[i].cnt,j-a[i].cnt+1));
else if(s[j] == '#'){
a[i].id = s.substr(j);
break;
}
}
}
for(int i=0;i<m;i++)
{
ans.clear();
query.clear();
char tmp[100];
scanf("%[^\n]",tmp);getchar();
char *sp=strtok(tmp," ");
while(sp)
{
query.push_back(toLower(sp));
sp=strtok(NULL," ");
}
int len=query.size();
for(int j=1;j<=n;j++)
{
if(query[len-1]==a[j].id||query[len-1]==a[j].lable)
{
int start=j,cnt=a[j].cnt,k=len-2;
for(;k>=0;k--)
{
if(!search(a,start,cnt,query[k])) break;
}
if(k<0)
ans.push_back(j);
}
}
cout<<ans.size();
for(int j=0;j<ans.size();j++)
cout<<" "<<ans[j];
cout<<endl;
}
return 0;
}