CCF--201809 元素选择器
题目太长(;´д`)ゞ大家看自己的吧~
这次的第三题终于是纯自己做出来的,开心,感谢之前让我爬上肩膀的巨人们!
这题相比其他时候的第三题温柔了不少,说说自己做题过程的一些注意点和思路吧:
1)标签大小不敏感,id 敏感,所以比较标签时要统一化为大写或小写;
2)因为要获得的是最终的子代行数,子代是主要矛盾点,所以我采用从子代倒推的思路:即先从最后开始找到子代,暂时保留结果,接着往前判断该子代是否符合匹配;
3)还有一点是我当初一直忽略的,是祖先有符合就行,并不一定是刚好上一代~(因为这个,卡了我好久。。。)
4)最后就是常规的用容器来存储去掉空格的信息,这跟之前URL那题一样。
嗯,这种题目就是要作死地练多几题~没有什么太多算法,就是文本的提取,按照题目一步步来~
hold 住,代码有点长:
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <algorithm>//结果排序 5 using namespace std; 6 struct HTML{ 7 int bank;//前导空格数 8 string name; 9 string id; 10 HTML(){ 11 bank=0; 12 } 13 }Stand[100];//去空格存储 每行 14 int n=0,m=0; 15 string Initial[100];//原始数据 16 vector<int> Final[10];//10行的向量数组 ,存行 17 int total[10]={0};//符合的组数; 18 void Transl(string str,int i)//去空格获信息 19 { 20 while(str[0]=='.'){ 21 Stand[i].bank++;//前导空格统计 22 str.erase(0,1);//删第一个字符 23 } 24 while(str[0]!=' '){ //遇间隔跳出 25 Stand[i].name+=str[0]; 26 str.erase(0,1); 27 if(str.empty()) { 28 Stand[i].id=""; 29 break;//无id时 30 } 31 } 32 //有id时 33 if(!str.empty()) str.erase(0,1);//去掉间隔 34 Stand[i].id=str; 35 } 36 int Count_bank(string judge) 37 { 38 int count=0; 39 for(int i=0;i<judge.size();i++) 40 { 41 if(judge[i]==' '){ 42 count++; 43 } 44 } 45 return count; 46 } 47 string TranName(string str)//全部转换为小写匹配 48 { 49 for(int i=0;i<str.size();i++) 50 { 51 if(str[i]<='Z'&&str[i]>='A') 52 { 53 str[i]+='a'-'A'; 54 } 55 } 56 return str; 57 } 58 bool Checkid(string str)//判断是否是id 59 { 60 if (str[0]=='#') return true; 61 return false; 62 } 63 bool Check_str(int temp_n,string str)//判断是否还有符合的最子代 64 { 65 if(Checkid(str)){//匹id 66 for(int i=temp_n;i>=0;i--) 67 { 68 if(Stand[i].id==str) return true; 69 } 70 return false; 71 } 72 else 73 {//匹name 74 for(int i=temp_n;i>=0;i--) 75 { 76 if(TranName(str)==TranName(Stand[i].name)) return true; 77 } 78 return false ; 79 } 80 81 } 82 //// 83 int main() 84 { 85 cin>>n>>m; 86 cin.get(); 87 int i=0,j=0; 88 for(i=0;i<n;i++) 89 { 90 getline(cin,Initial[i]);//原始数据 91 Transl(Initial[i],i); 92 } 93 string judge;//要匹配的 94 int ti=0;//第几个待匹配 95 int temp_m=m; 96 while(temp_m--) 97 { 98 getline(cin,judge); 99 int count=Count_bank(judge);//统计间隔 100 if(count==0)//单个元素 101 { 102 for(i=0;i<n;i++) 103 { 104 if(TranName(judge)==TranName(Stand[i].name)||judge==Stand[i].id) 105 { 106 total[ti]++; 107 Final[ti].push_back(i+1);//存行 108 } 109 } 110 } 111 else if(count>0)//多个元素 112 { 113 count++;//元素个数 114 string tran[100]; 115 string temp_str; 116 //先去间隔 finish 117 i=0; 118 while(!judge.empty()) 119 { 120 if(judge[0]!=' '){ 121 temp_str+=judge[0]; 122 judge.erase(0,1); 123 } 124 else{//==' ' 125 judge.erase(0,1); 126 tran[i]=(temp_str); 127 i++; 128 temp_str.clear(); 129 } 130 } 131 tran[i]=(temp_str);//得到待匹配的信息 132 //开始匹配从子代反推 133 int temp_n=n-1; 134 int temp_bank=0; 135 int temp_line=0; 136 while(Check_str(temp_n,tran[count-1])) 137 { 138 int judgenum=0;//统计匹配数 139 for(j=count-1;j>=0;j--)//逐个匹配 140 { 141 bool flag=Checkid(tran[j]); 142 for(i=temp_n;i>=0;i--) 143 { 144 if(flag) 145 {//匹id 146 if(tran[j]==Stand[i].id) 147 { 148 if(j==count-1) 149 {//最子代 150 judgenum++; 151 temp_n=i-1;//下一次起始顺前 152 temp_bank=Stand[i].bank-2;//初始子代的前导空格 153 temp_line=i+1; 154 break;//匹配则跳出 155 } 156 157 else{ //非最子代 158 if(Stand[i].bank<=temp_bank){//前导空格匹配 159 temp_bank=Stand[i].bank-2; 160 judgenum++; 161 break; //匹配 162 } 163 else continue; 164 } 165 } 166 } 167 else 168 {//匹name 169 if(TranName(tran[j])==TranName(Stand[i].name)) 170 { 171 if(j==count-1) 172 {//最子代 173 judgenum++; 174 temp_n=i-1;//下一次起始顺前 175 temp_bank=Stand[i].bank-2;//初始子代的前导空格 176 temp_line=i+1; 177 break;//匹配则跳出 178 } 179 else 180 { //非最子代 181 if(Stand[i].bank<=temp_bank){//前导空格匹配 是祖先即可 182 temp_bank=Stand[i].bank-2; 183 judgenum++; 184 break; //匹配 185 } 186 else continue; 187 } 188 } 189 } 190 } 191 192 } 193 if(judgenum==count) 194 { 195 total[ti]++; 196 Final[ti].push_back(temp_line); 197 } 198 } 199 200 } 201 ti++; 202 } 203 for(i=0;i<m;i++) 204 { 205 cout<<total[i]<<' '; 206 sort(Final[i].begin(),Final[i].end()); 207 for(j=0;j<Final[i].size();j++) 208 { 209 cout<<Final[i][j]<<' '; 210 } 211 cout<<endl; 212 } 213 return 0; 214 }
(`・ω・´)ゞ敬礼っ