我的思路:
这是一道模拟题,首先要读懂题目的要求。需要根据输入的元素建立一个树,类似于文件目录的查找。这里的节点可以用标签表示或者标签+id,其中标签可以忽略大小写,id最前方有一个‘#’且不忽略大小写。在查询方面,要注意可能有多级,需要判断好。这里实现的方法是对于查询路径逆向找父节点,这一行和这一行逐层向上的父节点都满足查询条件时,则记录答案。
我的总结:
一定要读懂题再开始coding,不要忽略了点的分层作用。。。
我的代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
string chang(string st){
for(int i=0;i<st.size();i++)
if(int(st[i])<97) st[i] = char(int(st[i])+32);
return st;
}
struct Ju{
string label,id;
int level,fa;
void init(string lab,string iid,int lev){
label = chang(lab);
id=iid;
level = lev;
fa=-1;
}
}ju[200];
stack<int > par;
int n,m,dex=1;
string ss,ss1,ss2;
string juu[90];
vector<int > ans;
bool che(Ju a,string b)
{
if(b[0]=='#')
{
return a.id==b;
}
else return a.label==chang(b);
}
int main()
{
cin>>n>>m;
char ch;
ch=getchar();
while(n--)
{
getline(cin,ss);
ss1=ss2="";
int ind=0,lev;
while(ss[ind]=='.') ind++;
lev=ind;
while(ss[ind]!=' '&&ind<ss.size()) ss1+=ss[ind++];
if(ind<ss.size())
{
ind++;
while(ind<ss.size()) ss2+=ss[ind++];
}
ju[dex].init(ss1,ss2,lev);
if(!par.empty())
{
while(!par.empty()&&ju[par.top()].level>=lev) par.pop();
if(par.empty()) ju[dex].fa = -1;
else ju[dex].fa=par.top();
}
par.push(dex);
dex++;
}
while(m--)
{
getline(cin,ss);
int inn=0;
juu[inn]="";
for(int i=0;i<ss.size();i++)
{
if(ss[i]==' ')
{
inn++;
juu[inn]="";
continue;
}
juu[inn]+=ss[i];
}
ans.clear();
for(int i=1;i<dex;i++)
{
int cur = inn;
if(che(ju[i],juu[cur]))
{
int tem = ju[i].fa;
cur--;
while(tem!=-1&&cur>=0)
{
if(che(ju[tem],juu[cur])) cur--;
tem=ju[tem].fa;
}
if(cur==-1) ans.push_back(i);
}
}
cout<<ans.size();
for(int i=0;i<ans.size();i++) cout<<" "<<ans[i];
cout<<endl;
}
return 0;
}