T2 - 消消乐大师——Q老师
题目
Input
Output
Sample Input
Sample Output
其他
解题思路
这是一道比较复杂的模拟题。
首先,输入具有两部分,一部分是文档内容,另一部分是待查询的选择器。这两部分都需要进行一定的处理。
对于文档内容部分,显然需要将其组织成一棵树的结构。
我们需要判断每个位置‘…’的个数来判断是哪一层。有下面几种情况:
- 如果是和目前所在的层一样,那就是当前层的兄弟节点,应该被连接到同一个父亲
- 如果是当前层的下一层,应该连接为当前层的儿子
- 如果是当前层前面的,就需要退回到上面的层进行处理
通过这三种情况,我们可以讲整个文档内容组织成一个树的结构,方便后续的查询和处理。
对于待查询的选择器部分,每个选择器都含有多个元素,所以对于每个选择器我们都应该进行处理。
我们将每个选择器的所有内容进行分割, 并存储在一起(在存储的时候标记是什么类型的)。
之后,开始在树中进行搜索。这里使用的方法是使用深度优先搜索,搜索时在树中依次查询,从上往下,层数小的优先进行匹配。重复这个过程直到查询结束。
完整代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
struct node;
struct link
{
link* next;
int hs;
};
struct node
{
int hs;
int pa;
string ys;
string id;
link* cld;
link* tail;
int cnt;
void add(int i)
{
link* p=new link;
p->hs=i;
p->next=NULL;
if(cnt==0)
{
cld=p;
tail=p;
}
else
{
tail->next=p;
tail=p;
}
cnt++;
}
};
struct ops
{
int kd;
string tag;
};
ops C;
vector<ops> V;
vector<int> vec_p;
node tree_[105];
string str;
int n,m,v_cnt,ff_n,vec_p_cnt,now_,cc;
void dfs(int i)
{
if(V[ff_n].kd==0)
{
if(tree_[i].ys==V[ff_n].tag)
{
if(ff_n==v_cnt-1)
{
vec_p.push_back(i);
link* p=tree_[i].cld;
while(p!=NULL)
{
dfs(p->hs);
p=p->next;
}
}else{
link* p=tree_[i].cld;
while(p!=NULL)
{
ff_n++;
dfs(p->hs);
ff_n--;
p=p->next;
}
}
}
else
{
link* p=tree_[i].cld;
while(p!=NULL)
{
dfs(p->hs);
p=p->next;
}
}
}
else
{
if(tree_[i].id==V[ff_n].tag)
{
if(ff_n==v_cnt-1)
{
vec_p.push_back(i);
link* p=tree_[i].cld;
while(p!=NULL)
{
dfs(p->hs);
p=p->next;
}
}
else
{
link* p=tree_[i].cld;
while(p!=NULL)
{
ff_n++;
dfs(p->hs);
ff_n--;
p=p->next;
}
}
}
else
{
link* p=tree_[i].cld;
while(p!=NULL)
{
dfs(p->hs);
p=p->next;
}
}
}
}
int main()
{
cin>>n>>m;
cin.get();
now_=-1;
cc=-1;
for(int i=1;i<=n;i++)
{
getline(cin,str);
int len=str.length(), c_cnt=0;
int p;
for(p=0;p<len;p=p+2)
{
if(str[p]=='.'&&str[p+1]=='.')
c_cnt++;
else
break;
}
char ys[85], hs[85];
int cc_1,cc_2;
cc_1=cc_2=0;
for(;p<len;p++)
{
if(str[p]!=' ')
{
if(str[p]>='A'&&str[p]<='Z')
str[p]=str[p]+32;
ys[cc_1++]=str[p];
}
else break;
}
string st_ys(ys,ys+cc_1);
for(;p<len;p++)
{
if(str[p]==' '||str[p]=='#')
continue;
else
hs[cc_2++]=str[p];
}
string st_hs(hs,hs+cc_2);
tree_[i].hs=i;
tree_[i].ys=st_ys;
tree_[i].id=st_hs;
if(c_cnt>cc)
{
if(now_==-1)
{
tree_[1].pa=-1;
}
else
{
tree_[now_].add(i);
tree_[i].pa=now_;
}
now_=i;
cc=c_cnt;
}
else if(c_cnt==cc)
{
tree_[tree_[now_].pa].add(i);
tree_[i].pa=tree_[now_].pa;
now_=i;
}
else if(c_cnt<cc)
{
while(c_cnt<cc)
{
now_=tree_[now_].pa;
cc--;
}
tree_[tree_[now_].pa].add(i);
tree_[i].pa=tree_[now_].pa;
now_=i;
}
}
for(int i=1;i<=m;i++)
{
V.clear();
vec_p.clear();
getline(cin,str);
char st_ss[85];
int cntS=0,rcdP=0;
C.tag="";
if(str[0]=='#')
{
C.kd=1;
}
else
{
C.kd=0;
if(str[0]>='A'&&str[0]<='Z')str[0]=str[0]+32;
st_ss[cntS++]=str[0];
}
for(int j=1;j<str.length();j++)
{
if(str[j]==' ')
{
string str2(st_ss+rcdP,st_ss+cntS);
C.tag=str2;
V.push_back(C);
rcdP=cntS;
j++;
if(str[j]=='#')
{
C.kd=1;
}
else
{
C.kd=0;
if(str[j]>='A'&&str[j]<='Z')
str[j]=str[j]+32;
st_ss[cntS++]=str[j];
}
}
else
{
if(C.kd==0&&str[j]>='A'&&str[j]<='Z')
str[j]=str[j]+32;
st_ss[cntS++]=str[j];
}
}
string str2(st_ss+rcdP,st_ss+cntS);
C.tag=str2;
V.push_back(C);
v_cnt=V.size();
ff_n=0;
dfs(1);
cout<<vec_p.size();
for(int i=0;i<vec_p.size();i++)cout<<" "<<vec_p[i];
cout<<endl;
}
}