codeforces Petya and Exam(模拟+哈希+细心分析)

本文解析了CodeForces上的一道题目,通过细致的逻辑分析解决了字符串匹配问题。介绍了如何利用hash表处理特殊字符,并提供了完整的C++实现代码。

题目链接:http://codeforces.com/contest/832/problem/B

题目大意:给出一个字符串,判断这个字符串是否合理,合理就输出yes

题目思路:对于?号和*号的位置需要用到hash存储,26个字母也类似,然后就开始判断,最清晰的思路应该是分析查询串是否含*号,以及查询串与母串长度的关系,从而做出相应的判断。

学到的东西:这类模拟题目要细心,把逻辑分析清楚再做相应的解答。所有的情况都要想明白

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e5+10;
int h[27];
int flag[maxn];
int main()
{
    fill(h,h+27,0);
    fill(flag,flag+maxn,0);
    string s1;cin>>s1;
    for(int i=0;i<s1.size();i++)
        if(s1[i]>='a'&&s1[i]<='z')
            h[s1[i]-'a'+1]=1;

    string tmp;cin>>tmp;
    int len = tmp.size();
    int have=0;
    for(int i=0;i<tmp.size();i++){
        if(tmp[i]=='?') flag[i]=1;
        if(tmp[i]=='*') {flag[i]=2;have=1;};
    }

    int n;cin>>n;
    while(n--){
        int is=0;
        string tmp2;cin>>tmp2;
        int t=0;
        int dis=tmp2.size()-tmp.size();
        if(!have){
            if(dis!=0) is=1;
        }
        for(int i=0;i<tmp2.size();i++,t++){
            if(tmp2.size()<len-1){
                    is=1;
                    break;
            }
            if(flag[t]==0){
                if(tmp2[i]-'a'!=tmp[t]-'a'){
                    is=1;break;
                }
            }
            if(flag[t]==1){
                if(h[tmp2[i]-'a'+1]!=1){
                    is=1;break;
                }
            }
            if(flag[t]==2){
                if(dis>=0){
                        dis++;
                while(dis--){
                    if(h[tmp2[i]-'a'+1]){
                        is=1;break;
                    }
                    i++;
                }
                i--;
                }
                else
                    i--;
            }
            //if(flag[t]==2&&h[tmp2[i]-'a'+1]) t++;
        }
        if(is) cout<<"NO"<<endl;
        else cout<<"YES"<<endl;
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值