题意
题目链接:http://118.190.20.162/view.page?gpid=T77
解题思路
顺序记录每个元素的标签、id、层数(缩进个数), 由于标签大小写不敏感,全转换为小写。
查询时,使用vector记录选择器的每一项,逐个判断每个元素是否符合该选择器。对于后代选择器,需对元素向前查找所有祖先判断是否符合。
代码
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <sstream>
#include <vector>
using namespace std;
struct Element{
string label;
string id;
int k;
}e[105];
int n, m;
int main(){
cin >> n >> m;
cin.get();
for(int i = 1; i <= n; ++i){
string s;
getline(cin, s);
int cnt = 0;
while(s[cnt] == '.') cnt++;
e[i].k = cnt / 2;
string str;
while(s[cnt] != ' ' && cnt < s.length()){
str += s[cnt];
cnt++;
}
transform(str.begin(), str.end(), str.begin(), ::tolower);
e[i].label = str;
if(cnt < s.length()){
string temp;
while(++cnt < s.length())
temp += s[cnt];
e[i].id = temp;
}
}
for(int i = 1; i <= m; i++){
string s;
getline(cin, s);
stringstream ss(s);
string temp;
vector<string> v;
vector<int> ans;
while(ss >> temp)
v.push_back(temp);
for(int k = 0; k < v.size(); k++)
if(v[k][0] != '#')
transform(v[k].begin(), v[k].end(), v[k].begin(), ::tolower);
for(int k = n; k > 0; k--){
if(e[k].id == v[v.size() - 1] || e[k].label == v[v.size() - 1]){
int cnt = v.size() - 2, curk = e[k].k;
for(int j = k; j > 0; j--){
if(cnt < 0) break;
if(e[j].k < curk){
curk = e[j].k;
if(e[j].id == v[cnt] || e[j].label == v[cnt])
cnt--;
}
}
if(cnt == -1) ans.push_back(k);
}
}
cout << ans.size();
for(int k = ans.size() - 1; k >= 0; --k)
cout << ' ' << ans[k];
cout << endl;
}
return 0;
}