CCF CSP元素选择器
结果
解析
利用bfs,这道题细节问题一方面是标签大小写不敏感,另一方面是祖先的祖先仍然是该元素的祖先
#include <bits/stdc++.h>
using namespace std;
const int maxn=101;
vector<int> v[maxn];
map<int,int> mp;
vector<string> vs;
bool isvisited[maxn];
int n;
struct node{
string str;
string id;
}p[maxn];
struct state{
int k;
int num;
state(int k,int num):k(k),num(num){}
};
queue<state> q,u;
string calstring(string str){
int cos=str.size();
if(str[0]!='#')
for(int i=0;i<cos;i++)
if(isalpha(str[i]))
str[i]=tolower(str[i]);
return str;
}
void findinit(int num,int k){
string s=vs[k-1];
if(k==1){
if(s[0]=='#'){
for(int i=1;i<=n;i++)
if(p[i].id==s){
q.push(state(k,i));
}
}
else if(s[0]!='#'){
for(int i=1;i<=n;i++){
if(p[i].str==s){
q.push(state(k,i));
}
}
}
}
else{
int cos=v[num].size();
if(s[0]=='#'){
for(int i=0;i<cos;i++){
q.push(state(k-1,v[num][i]));
if(p[v[num][i]].id==s)
q.push(state(k,v[num][i]));
}
}
else if(s[0]!='#'){
for(int i=0;i<cos;i++){
q.push(state(k-1,v[num][i]));
if(p[v[num][i]].str==s)
q.push(state(k,v[num][i]));
}
}
}
}
void findstring(int num){
while(!q.empty()){
state t=q.front();
q.pop();
if(t.k<num){
findinit(t.num,t.k+1);
}
else
if(!isvisited[t.num]){
isvisited[t.num]=true;
u.push(t);
}
}
}
void init(string str,int i,int num){
string s;
if(str.find(' ')!=string::npos){
int start=str.find(' ');
s=str.substr(num,start-num);
p[i].str=calstring(s);
p[i].id=str.substr(start+1);
}
else{
s=str.substr(num);
p[i].str=calstring(s);
p[i].id="";
}
map<int,int>::iterator it;
if(num!=0)
for(it=mp.begin();it!=mp.end();it++)
if(it->first==num-2)
v[it->second].push_back(i);
mp[num]=i;
}
int getsnum(string str){
int start=0,num=0,end;
string s;
while(str.find(' ',start)!=string::npos){
end=str.find(' ',start);
s=str.substr(start,end-start);
s=calstring(s);
vs.push_back(s);
start=end+1;
num++;
}
s=str.substr(start);
s=calstring(s);
vs.push_back(s);
num++;
return num;
}
int getpnum(string str){
int sum=0;
int num=str.size();
for(int i=0;i<num;i++){
if(str[i]=='.')
sum++;
else
return sum;
}
return sum;
}
int main(){
int m,num;
cin>>n>>m;
getchar();
for(int i=1;i<=n;i++){
string str;
getline(cin,str);
num=getpnum(str);
init(str,i,num);
}
for(int i=1;i<=m;i++){
string str;
vs.clear();
getline(cin,str);
num=getsnum(str);
memset(isvisited,false,sizeof(isvisited));
findinit(0,1);
findstring(num);
cout<<u.size()<<" ";
if(!u.empty()){
while(!u.empty()){
state t=u.front();
u.pop();
cout<<t.num<<" ";
}
}
cout<<endl;
}
}