【CCF-CSP】201809-3 元素选择器

 原题链接:计算机软件能力认证考试系统

深度优先搜索,将每一个查询根据空格分割成若干子串,一级一级搜索,下一级行数比当前行数大,且等级比当前等级高(这里定义等级与'.’的个数成正比,等级高者为后代),当搜索完最后一级时,即找到了一个满足要求的答案。

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#define N 110
using namespace std;

int n,m,ran[N];//ran[i]存储第i行的等级,等级越大辈分越小,等级可由'.'的个数确定
string str[N],ss;
set<int> ret;//存储查询结果
vector<string> s;//将查询内容按空格分隔开

void dfs(int st,int d,int r){//st为遍历起点;d为当前搜索的第几个字符串,与s中存储的子串一致,从0开始;r为上一个子串的等级
    if(d==s.size()){//搜索完所有的子串
        ret.insert(st-1);
        return;
    }
    for(int i=st;i<=n&&ran[i]>r;i++){//剪枝:ran[i]>r,当前的等级必须大于上一等级
        int p=str[i].find(s[d]);//查找是否存在第d个子串,下面判断搜索是否合理
        if(p!=-1&&(p==0||str[i][p-1]==' '||str[i][p-1]=='.')&&(p+s[d].size()==str[i].size()||str[i][p+s[d].size()]==' ')){
            dfs(i+1,d+1,ran[i]);//搜索下一个子串
        }
    }
}

int main()
{
    cin>>n>>m;
    getchar();

    for(int i=1;i<=n;i++){
        getline(cin,str[i]);
        int p=str[i].find_first_not_of('.');
        ran[i]=p/2;//存储等级
        while(p!=str[i].size()&&str[i][p]!=' '){//标签对大小写不敏感,统一记为小写
            str[i][p]=tolower(str[i][p]);
            p++;
        }
    }
    for(int i=1;i<=m;i++){
        getline(cin,ss);
        ret.clear();
        s.clear();
        ss+=' ';
        int pre=-1,p;
        while((p=ss.find(' ',pre+1))!=-1){//按空格分割开,便于一级一级搜索
            string sub=ss.substr(pre+1,p-pre-1);
            if(sub[0]!='#') //标签统一记为小写
                transform(sub.begin(),sub.end(),sub.begin(),::tolower);
            s.push_back(sub);
            pre=p;
        }
        dfs(1,0,-1);//搜索
        cout<<ret.size();
        for(auto it=ret.begin();it!=ret.end();it++)
            cout<<" "<<*it;
        cout<<endl;
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值