CSP201809-3 元素选择器

思路:

复杂模拟题

采用结构体存储元素信息,输入时,统一化为大写或小写。

考虑三种元素选择器
标签/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 }

 

posted @ 2020-06-06 10:07  流转~星云  阅读(202)  评论(0编辑  收藏  举报