思路:
复杂模拟题
采用结构体存储元素信息,输入时,统一化为大写或小写。
考虑三种元素选择器
标签/id选择器:
直接遍历整个数组 分别与label/id作比较即可
*后代选择器:
①.首先遍历一遍元素 找出符合最后一个条件的所有元素 放入一个vector中
②.对vector中的每个元素
首先判断倒数第二个条件
从该元素的上一行开始 如果找到满足条件的行 并且level 满足a[k].level<levels 说明当前满足条件
此时要将levels更新为a[k].level
接着判断倒数第三个条件
从上一次停下的位置开始
1 #include<iostream> 2 #include<algorithm> 3 #include<math.h> 4 #include<string> 5 #include<string.h> 6 #include<stdio.h> 7 #include<vector> 8 #include<map> 9 #include<sstream> 10 using namespace std; 11 int n,m,tnt; 12 struct node 13 { 14 string label;//标签 大小写不敏感 故可以全部转化为小写字母存储 15 string id;//id属性 16 int level; 17 }a[110]; 18 string s; 19 //后代选择器用贪心的思路写 20 //吧记录祖先 改为记录后代 21 //并且记录后代时 需要划分后代的等级 因为需要贪心 22 int main() 23 { 24 cin>>n>>m;getchar(); 25 int N=n,M=m; 26 while(N--)//将结构化文档初始读入 且记录前驱 27 { 28 tnt++; 29 getline(cin,s); 30 int levels=1,tmp=0; 31 while(tmp<s.length()) 32 { 33 if(s[tmp]!='.'||s[tmp+1]!='.') break; 34 tmp+=2; 35 levels++; 36 } 37 a[tnt].level=levels; 38 int i=1; 39 int idx=s.find(' '); 40 if(idx!=s.npos)//label 和 id 41 { 42 a[tnt].label=s.substr(tmp,idx-tmp); 43 a[tnt].id=s.substr(idx+1,s.length()-(idx+1)); 44 } 45 else a[tnt].label=s.substr(tmp,s.length()-tmp); 46 47 transform(a[tnt].label.begin(),a[tnt].label.end(),a[tnt].label.begin(),::tolower); 48 } 49 50 while(M--) 51 { 52 getline(cin,s); 53 int idx=s.rfind(' ',s.length()),last=s.length(); 54 if(idx==-1)//说明是标签选择器或id选择器 55 { 56 vector<int> ans; 57 int tot=0; 58 if(s[0]=='#')//id选择器 59 { 60 for(int i=1;i<=n;i++) 61 { 62 if(a[i].id.compare(s)==0) 63 { 64 tot++; 65 ans.push_back(i); 66 } 67 } 68 cout<<tot<<" "; 69 for(auto &entry:ans) cout<<entry<<" "; 70 cout<<endl; 71 } 72 else//标签选择器 73 { 74 transform(s.begin(),s.end(),s.begin(),::tolower); 75 for(int i=1;i<=n;i++) 76 { 77 if(a[i].label.compare(s)==0) 78 { 79 tot++; 80 ans.push_back(i); 81 } 82 } 83 cout<<tot<<" "; 84 for(auto &entry:ans) cout<<entry<<" "; 85 cout<<endl; 86 } 87 } 88 else//后代选择器 89 { 90 vector<int> ans; 91 vector<string> limits; 92 stringstream ss(s); 93 while(ss>>s) 94 {limits.push_back(s);} 95 //先选择满足最后条件的 96 string tmp=limits.back(); 97 if(tmp[0]=='#') 98 { 99 for(int i=1;i<=n;i++) 100 if(a[i].id.compare(tmp)==0) ans.push_back(i);//可能是答案的 我们先记录下来 101 } 102 else 103 { 104 transform(tmp.begin(),tmp.end(),tmp.begin(),::tolower); 105 for(int i=1;i<=n;i++) 106 if(a[i].label.compare(tmp)==0) ans.push_back(i);//可能是答案的 我们先记录下来 107 } 108 109 int ans_tnt=ans.size(); 110 //处理前面的条件 111 for(int i=0;i<ans.size();i++) 112 { 113 int idx=ans[i],levels=a[idx].level,now=idx-1; 114 int tot=0; 115 for(int j=limits.size()-2;j>=0;j--) 116 {//从idx向前找 找到一个则更新初始的位置 117 for(int k=now;k>=0;k--) 118 { 119 if(limits[j][0]=='#') 120 { 121 if(a[k].id.compare(limits[j])==0&&a[k].level<levels) 122 { 123 tot++; 124 now=k-1; 125 levels=a[k].level; 126 break; 127 } 128 } 129 else 130 { 131 if(a[k].label.compare(limits[j])==0&&a[k].level<levels) 132 { 133 tot++; 134 now=k-1; 135 levels=a[k].level; 136 break; 137 } 138 } 139 140 } 141 } 142 if(tot!=limits.size()-1) 143 { 144 ans[i]=-1; 145 ans_tnt--; 146 } 147 } 148 cout<<ans_tnt<<" "; 149 for(auto &entry:ans) 150 if(entry!=-1) cout<<entry<<" "; 151 cout<<endl; 152 } 153 154 } 155 return 0; 156 }