题意介绍
题意分析
模拟题,每一行都处理成一个结构体,包括级别、标签、id。级别为点数量的二分之一,还要把元素名称全部变为小写,处理查询时,如果输入的一行只有一个单词,则遍历所有结构体查找即可,如果有多个单词,则找到查询语句的最后一个单词,并且从后往前遍历找到他的祖先。
通过代码
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int num;
string label;
string id;
};
int n, m;
vector<Node>nodes;
vector<string>re;
string toLower(string label)//为了把字符串变成小写,因为label对大小写不敏感
{
for (int i = 0; i < label.length(); i++)
{
if (label[i] >= 'A'&&label[i] <= 'Z')
{
int num = label[i] - 'A';
label[i] = num + 'a';
}
}
return label;
}
void split(string t) //分割字符串
{
int i;
int pos1 = 0, pos2 = 0;
while ((pos2 = t.find(' ', pos1)) != string::npos)
{
string s = t.substr(pos1, pos2 - pos1);
s = toLower(s);
re.push_back(s);
pos1 = pos2 + 1;
}
string s = t.substr(pos1, t.length() - pos1);
if (s[0] != '#') //label是大小写不敏感的
s = toLower(s);
re.push_back(s);
}
void reAns()
{
int i, j, k;
queue<int>st;
for (i = 0; i < n; i++)
{
int flag = 0;//为1表示不匹配
int in = 0;//为0表示最一个选择器就找不到匹配(如h3)
string t1 = re[re.size() - 1];//最后一个开始,然后找祖宗,倒序找
if (t1 == nodes[i].label || t1 == nodes[i].id)
{
in = 1;
int t_num = re.size() - 2;
for (j = i - 1; j >= 0; j--)
{
if (t_num < 0)//找完了退出
{
break;
}
t1 = re[t_num];
if (nodes[j].num <= nodes[i].num)
{
if (nodes[j].num < nodes[i].num && (t1 == nodes[j].label || t1 == nodes[j].id))
{
t_num--;
continue;
}
}
else
{
flag = 1;
break;
}
}
if ((j == -1 && t_num >= 0) || !in)//全部规则都找遍了都没有找到,或者还有祖宗没有匹配.
{
flag = 1;
}
if (flag == 0)
st.push(i + 1);
}
}
cout << st.size() << " ";
while (!st.empty())
{
cout << st.front() << " ";
st.pop();
}
cout << endl;
}
int main()
{
int i, j, k;
string t;
Node node;
cin >> n >> m;
getchar();
for (i = 0; i < n; i++)
{
node.id = ""; node.num = 0; node.label = "";
while (getline(cin, t))
{
int t_i = 0;
if (t[t_i] == '.')
{
while (t[++t_i] == '.');
node.num = t_i / 2;
}
//找id
int pos;
if ((pos = t.find(' ', t_i)) != string::npos)//说明有标签
{
node.label = toLower(t.substr(t_i, pos - t_i));
pos = t.find('#', pos);
node.id = t.substr(pos, t.length() - pos);
nodes.push_back(node);
break;
}
else
{
node.label = toLower(t.substr(t_i, t.length() - t_i));
nodes.push_back(node);
break;
}
}
}
for (i = 0; i < m; i++)
{
re.clear();
getline(cin, t);
split(t);
reAns();
}
return 0;
}