题目大意:
给一个html文档,每一行又 ".",标签,id组成,如果上一层的点是下一层点+2,中间还没有比上一层相等以及更少的语句,那么这就形成一个子语句,然后查询就是题目中说的了。
首先各位有没有代码都读烂了的情况下,但是就是卡在80分的情况,我们先来看看这一句。
后代选择器,A和B均为标签选择器或id选择器,这句话是有歧异的。
如果你卡在80分,那么我们读到的题目一定是这样的(A和B均为标签选择器 )或者 (A和B均为id选择器)。
而题目的意思是 (A为标签选择器或id选择器) 并且 (B为标签选择器或id选择器)(这不废话吗?你一共也就给了两种啊)
解题步骤:
1. 把所有读入的字符串都分割成一个结构体,包括 ( 点的个数 , id ,标签 )
三个部分后两者是string类型。
2. 把所有的id , 标签映射成一个int类型的数字,也就是 map<string , int>mp,mp2。
3. 使用映射好的map , 讲对应的行塞入相应的vector
比如,第5行和第6行有 ”mznb“ 这个标签,那么
就在要”mznb“这个对应的vector push 5和6(标签用v1,id用v2)
4. 建立父子关系,遍历整个字符串,然后前边第一个比他少俩点的就是他父亲。
5. 查询,无论查询是标签选择器还是id选择器,我们全部按复合选择器处理。
先使用刚刚的两个vector中的一个,找到最后一个标签的位置
比如html div p , 那么我们把所有标签为p的位置
都使用代码中的check函数去跳父亲。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll MAXN = 10005;
struct node
{
int id,len,num_d;
string s,q,h;
}C[MAXN];
vector<int>v1[MAXN],v2[MAXN];
map<string,int>mp,mp2;
int tot,tot2;
int n,m;
int fa[MAXN];
void fun(int i)
{
int num = 0;
int len = (C[i].s).size();
for(int j=0;j<len;j++){
if(C[i].s[j] == '.')num++;
else break;
}
C[i].num_d = num;
int idx = -1;
for(int j=0;j<len;j++){
if(C[i].s[j] == '#')idx = j;
}
string k = "";
if(idx != -1){
for(int j=idx;j<len;j++){
k += C[i].s[j];
}
//cout<<k<<endl;
if(!mp2[k])mp2[k] = ++tot2;
v2[mp2[k]].push_back(i);
}
C[i].h = k;
k = "";
for(int j =0;j<len;j++){
if(C[i].s[j] == '.')continue;
if(C[i].s[j] == ' ')break;
if(C[i].s[j]>='A' && C[i].s[j]<='Z')C[i].s[j] = C[i].s[j]-'A'+'a';
k += C[i].s[j];
}
C[i].q = k;
if(!mp[k])mp[k] = ++tot;
v1[mp[k]].push_back(i);
}
string cx[MAXN];
vector<int>ans;
int tot_q = 0;
bool check(int x,int flag)
{
int now = tot_q;
int now_id = x;
while(now>=1&&now_id!=0){
if(C[now_id].q == cx[now] || C[now_id].h == cx[now]){
now--;
}
now_id = fa[now_id];
}
return (now == 0);
}
int main()
{
fa[1] = 0;
scanf("%d%d",&n,&m);
getchar();
for(int i=1;i<=n;i++){
getline(cin,C[i].s);
C[i].len = (C[i].s).size();
fun(i);
}
for(int i=n;i>=1;i--){
int nd = C[i].num_d;
for(int j=i-1;j>=1;j--){
if(C[j].num_d == nd-2){
fa[i] = j;
break;
}
}
}
while(m--)
{
ans.clear();
tot_q = 0;
string q;
getline(cin,q);
string k = "";
int len = q.size();
for(int i=0;i<=len;i++){
if(q[i] == ' ' || i == len){
cx[++tot_q] = k;
k = "";
}
else{
k += q[i];
}
}
bool f = 1;
if(cx[tot_q][0] == '#')f = 0;
for(int i=1;i<=tot_q;i++){
if(cx[i][0] == '#')continue;
int len =cx[i].size();
for(int j=0;j<len;j++){
if(cx[i][j]>='A' && cx[i][j]<='Z')
cx[i][j] = cx[i][j] - 'A' +'a';
}
}
if(f){
int id = mp[cx[tot_q]];
int len = v1[id].size();
for(int i=0;i<len;i++){
int to = v1[id][i];
if(check(to,1))ans.push_back(to);
}
}
else{
int id = mp2[cx[tot_q]];
int len = v2[id].size();
for(int i=0;i<len;i++){
int to = v2[id][i];
if(check(to,0))ans.push_back(to);
}
}
int le = ans.size();
cout<<le;
for(int i=0;i<le;i++){
cout<<" "<<ans[i];
}
cout<<endl;
}
}
/*
11 5
html
..head
....title
..body
....h1
....p #subtitle
....div #main
......h2
......p #one
......div
........p #two
p
#subtitle
h3
div p
div div p
11 90
html
..head
....title
..body
....h1
....p #subtitle
....div #main
......h2
......p #one
........p #two
..........p #two
#subtitle #two
#main #one #two
html head title
*/