程序设计思维月模拟4 CSP201809-3 元素选择器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
思路
看到题目还以为是化学背景的题,仔细读题后发现里面的细节问题很多,由于写这类复杂模拟题不熟练,一时间想不到好的解决办法。
回顾这道题,整理了一些关键的点,也适合再遇到这类模拟题时寻找写代码的切入点。
①元素统一格式开结构体,没有ID就设为空值。因为是在树结构上查找而且没有修改结构的操作,用下标记录每个元素所处的level
②字母一律转为小写,和①都体现了格式统一化的思想,看上去增加了开支但实际上省去不少麻烦
③查询有多个字符串的情况,由最后一个往上层去查找
其余要强调的部分写在注释里

#include<iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <cstring>
#include <queue>
#include <sstream>
using namespace std;
#define ll long long
vector<int> ans;
vector<string> query;
struct node
{
    string label;
    string id;
    int lv;
}elements[101];
void alphalower(string &s0)//转为小写
{
    for(int i=0;i<s0.length();i++)
    {
        ixf(isalpha(s0[i]))
        {
            s0[i] = tolower(s0[i]);
        }
    }
}
void init(string s,int ind)
{
    string label,id;
    int flg = 0,pos_label = 0,pos_id = 0,pcnt = 0;
    for(int i=0;i<s.length();i++)
    {
        if(s[i] == '.')pcnt++;
        if(s[i]!='.'&&flg == 0)
        {
            flg = 1;
            pos_label = i;
        }
        if(s[i] == ' ' && flg == 1)
        {
            flg = 2;
            pos_id = i+1;
            break;
        }
    }
    if(flg == 2)
    {
        label = s.substr(pos_label,pos_id - 1 - pos_label);
        alphalower(label);
        id = s.substr(pos_id);
        elements[ind].label = label;
        elements[ind].id = id;
        elements[ind].lv = pcnt/2;
    }
    else
    {
        label = s.substr(pos_label);
        alphalower(label);
        elements[ind].label = label;
        elements[ind].lv = pcnt/2;
    }
}
bool check(int ind)
{
    int temp = elements[ind].lv,p = query.size()-1 - 1;
    for(int i=ind-1;i>=1;i--)//向上查找
    {
        if(elements[i].lv == temp - 1)//正好是父亲
        {
            if(query[p][0] != '#' && query[p] == elements[i].label)
            {
                p--;//标签匹配
            }
            else if(query[p][0] == '#' && query[p] == elements[i].id)
            {
                p--;//id匹配
            }
            temp = elements[i].lv;
            if(p<0)return true;
        }
    }
    return false;//p没有遍历完说明不合法,匹配失败
}
int main()
{
    int n,m;
    string s;
    scanf("%d%d",&n,&m);
    getchar();
    for(int i=1;i<=n;i++)
    {
        getline(cin,s);
        init(s,i);
    }
    for(int i=0;i<m;i++)
    {
        getline(cin,s);
        stringstream ss;
        ss<<s;
        string ques;
        while (ss>>ques)
        {
            if(ques[0]!='#')
            {
                alphalower(ques);
            }
            query.push_back(ques);
        }
        int qsize = query.size();
        for(int j=1;j<=n;j++)
        {
            if((query[qsize-1][0] != '#' && elements[j].label == query[qsize-1])
            || (query[qsize-1][0] == '#' && elements[j].id == query[qsize-1]))
            {
                if(qsize == 1)ans.push_back(j);
                else if(check(j))ans.push_back(j);
            }
        }
        printf("%d",ans.size());
        for(int k=0;k < ans.size();k++)
        {
            printf(" %d",ans[k]);
        }
        printf("\n");
        ans.clear();
        query.clear();
    }
    return 0;
}
/*
11 5
html
..head
....title
..body
....h1
....p #subtitle
....div #main
......h2
......p #one
......div
........p #two

 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值