PTA 字符串约束

给定一个只包含下划线和大写字母的字符串,将下划线全部换成大写字母,问有多少种填法能使这个字符串满足以下三种要求:

  • 不包含三个及以上连续的元音字母;
  • 不包含三个及以上连续的辅音字母;
  • 至少包含一个大写字母 L。

元音字母仅包含A,E,I,O,U,其他的字母都是辅音字母。

输入格式:

输入的一行给出一行字符串S;

∣S∣≤100

题目保证最多含有10个下划线,并且只会出现大写字母和下划线。

输出格式:

输出一个整数——表示方案数。

输入样例:

L_V

输出样例:

5

输入样例:

JA_BU_K_A

输出样例:

485

解题思路:

        一开始拿到题目的时候是懵比的,想了好久,一开始的思路是在每个下划线上都放入一个合适的元音字母或者辅音字母,同时计录个数,最后全部放完之后判断原本字符串是否有‘L’的存在,如果不存在,辅音的个数要-1(但是如果连续遇到好多的连续下划线就会导致无法仿制,只能去一步步地尝试)。

因此我们倒不如直接尝试,(反正最多也就10个下划线)。用一个新的字符串来记录,所有的元音字母全部变为1,所有的‘L‘全部变成0,所有的除'L'的辅音字母全部变成2(这一步是为了最后全部放完之后字符串的合法性),加元音时,总数*5,加辅音时,总数*20,加’L‘时,不进行变化。最后合法了,总个数加上当前的个数就是正解。

下面是ac代码:

#include<bits/stdc++.h>
using namespace std;
string s;
long long ans;
int f=0;
string ss="";
void dfs(int tep,long long sum){
    if(tep==s.size()){
        int a=ss.find("0");
        if(a==-1){
            return ;
        }
        int f=0;
        for(int i=1;i<ss.size()-1;i++){
            if(ss[i]=='1'){
                if(ss[i-1]=='1' && ss[i+1]=='1'){
                    f=1;
                    break;
                }
            }
            if(ss[i]=='2' || ss[i]=='0'){
                if(ss[i-1]=='0' || ss[i-1]=='2'){
                    if(ss[i+1]=='0' || ss[i+1]=='2'){
                        f=1;
                        break;
                    }
                }
            }
        }
        if(!f){
            ans+=sum;
        }
        return ;
    }
    if(s[tep]=='A' || s[tep]=='E' || s[tep]=='I' || s[tep]=='O' || s[tep]=='U'){
        ss+="1";
        dfs(tep+1,sum);
        ss.pop_back();
    }else if(s[tep]=='_'){
        ss+="1";
        dfs(tep+1,sum*5);
        ss.pop_back();
        ss+="2";
        dfs(tep+1,sum*20);
        ss.pop_back();
        ss+="0";
        dfs(tep+1,sum);
        ss.pop_back();
    }else if(s[tep]=='L'){
        ss+="0";
        dfs(tep+1,sum);
        ss.pop_back();
    }else{
        ss+="2";
        dfs(tep+1,sum);
        ss.pop_back();
    }
}
void solve(){
    cin>>s;
    f=0;
    ans=0;
    dfs(0,1);
    cout<<ans<<endl;
}
int main(){
    int t=1;
    while(t--){
        solve();
    }
    return 0;
}

  • 34
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值