CCF CSP 201809-3 元素选择器
这题考验思路的清晰和对细节的把握;
刚开始不会写的时候翻了很多大佬们的代码,他们都说简单,萌新瑟瑟发抖…
在参考其它大佬们的代码时也发现了他们的一些bug,例如按题目中的样例,用h1 h2去测试的时候,有些博主的代码会输出1 8,但实际上这是一个树状结构,理应输出0,希望大家在参考其它大佬的代码时不要产生和我一样的疑惑^ _ ^
题目:
题目略长直接放链接了~
201809-3 元素选择器
思路:
1.定义结点的结构体,然后用树来存储整个结构化文档;
2.在处理label时注意忽略大小写,直接将所有label转成小写即可;
3.对于每一个查询,以空格为分隔,将所有子选择器倒序存放在数组中,然后dfs整颗树,在树中找数组中的第一个元素,找到了的话我们依次查找这个结点的祖先结点,去判断这个数组剩下的部分是否按序存在在它到根节点的路径中;
例如查询div div p,在数组中为{p,div,div},第11行的p到根节点的路径为p、div、div(#main)、body、html、root,显然该数组中的元素是该序列的一个子序列,所以第11行的p就符合;同理其它的p不符合条件;
代码:
#include<bits/stdc++.h>
using namespace std;
void tolwr(string & s){
for(int i=0;i<s.length();i++) s[i]=tolower(s[i]);
}
struct tree{
string label,id;
int level;
tree *parent;
vector<tree *> chd;
tree(){this->level=0;}
tree(string label,string id,tree *parent,int level){
this->label=label;this->id=id;
this->parent=parent;this->level=level;
}
};
vector<string> v;
int ans=0;
vector<int> rs;
void dfs(tree *p){
if(p->label==v[0]||p->id==v[0]){
tree *q=p->parent;
int i;
for(i=1;i<v.size()&&q->level;q=q->parent)
if(q->label==v[i]||q->id==v[i]) i++;
if(i==v.size()){
ans++;
rs.push_back(p->level);
}
}
for(auto e:p->chd) dfs(e);
}
int main(){
int n,m;
cin>>n>>m;
getchar();
tree *root=new tree();
tree *p=root;
int pre_pos=-3;
for(int i=1;i<=n;i++){
string name,label,id="";
getline(cin,name);
int label_pos=name.rfind('.');
int id_pos=name.find('#');
if(label_pos<0||label_pos>100) label_pos=-1;
if(id_pos<0||id_pos>100) id_pos=name.length()+1;
label=name.substr(label_pos+1,id_pos-label_pos-2);
tolwr(label);
if(id_pos<name.length()){
id=name.substr(id_pos,name.length()-id_pos);
}
if(label_pos-pre_pos==4){
pre_pos+=2;
p=p->chd[p->chd.size()-1];
}else if(label_pos<=pre_pos){
for(int j=(pre_pos-label_pos)/2;j>=0;j--) p=p->parent;
pre_pos=label_pos-2;
}
tree *t=new tree(label,id,p,i);
p->chd.push_back(t);
}
for(int i=0;i<m;i++){
string query;
getline(cin,query);
v.clear();
ans=0;
rs.clear();
for(int p=query.length()-1,q=p;p>=0;p--,q=p){
while(query[p]!=' '&&p>=0) p--;
string s=query.substr(p+1,q-p);
if(s[0]!='#') tolwr(s);
v.push_back(s);
}
dfs(root);
cout<<ans;
for(auto e:rs) cout<<' '<<e;
putchar('\n');
}
return 0;
}