Balanced Strings(模拟+讨论)

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
题意:给出主串,问构成给出的一个主串中的所有偶数长度的连续子字符串并且所有连续的子字符串中元音字母个数等于辅音字母个数;问构成满足这样的主串的方法一共有多少种?其中元音有a,e,i,o,u,y,6种,辅音有20种;给出主串?上面可以填元音或者辅音;

其实这道题就是考阅读。。。当时比赛没注意这道题,结果下来补题的时候才知道这个比H简单多了,直接模拟就A了;根据题目要求,不难发现题目中说的所有偶数长度,那么最小的偶数长度就是2,所以我只需要保证相邻的字符一个是元音一个是辅音就可以了;
下面来分类讨论:
在这里插入图片描述
其中红色圈圈表示这中是不可能构成的,所以输出0;
注意一个全为?的主串,分为奇数和偶数;
比如:在这里插入图片描述
其余情况只需要枚举即可;
因为元音左右只能放辅音,辅音左右只能放元音,所以枚举一下然后最后检查一遍即可;
具体看代码:
AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll QP(ll x,ll n){
    
    
	ll res=1;
	while(n){
    
    
		  if(n&1){
    
     
		    res=res*x;
		  }
		  x*=x;
		  n>>=1;
	}
	return res;
}
bool vowel(char c){
    
    
	return c=='a'||c=='e'||c=='i'||c=='o'||c=='u'||c=='y';
}
int main(){
    
    
	int T;
	scanf("%d",&T);
	int g=1;
	while(T--){
    
    
       string s;
       cin>>s;
        ll num=0;
        for(int i=0;i<s.length();i++)if(s[i]=='?')num++;
        if(num==s.length()){
    
    //如果说全是? 
        	if(num%2==0){
    
    
        		printf("String #%d: %lld\n",g++,2*QP(20,num/2)*QP(6,num/2));
			}else{
    
    
				printf("String #%d: %lld\n",g++,QP(20,num/2+1)*QP(6,num/2)+QP(20,num/2)*QP(6,num/2+1));
			}
		}else{
    
    
			ll ans=1;
			int f=0;
			for(int i=1;i<s.length()-1;i++){
    
    
				if(s[i]=='?'){
    
    
				if(s[i-1]!='?'&&s[i+1]!='?'){
    
    
				  if((vowel(s[i-1])&&!vowel(s[i+1]))||(!vowel(s[i-1])&&vowel(s[i+1]))){
    
    //前是元音,后面是辅音或者前面是辅音,后面是元音,这种情况直接不成立了 
				  	 f=1;break;
				  }
			     }
			   }else{
    
    
			   	  if(s[i-1]!='?'){
    
    //相邻两个已知的情况下 如果相邻是元音或者为辅音,那么肯定答案就是0了
			   	  	   if((vowel(s[i])&&vowel(s[i-1]))||(!vowel(s[i])&&!vowel(s[i-1])))f=1;break;
					 }else if(s[i+1]!='?'){
    
    
					 	 if((vowel(s[i])&&vowel(s[i+1]))||(!vowel(s[i])&&!vowel(s[i+1])))f=1;break;
					 }
			   }
			}
			if(f) printf("String #%d: 0\n",g++);
			else {
    
    
				int index;
				for(int i=0;i<s.length();i++){
    
    
					   if(s[i]<='z'&&s[i]>='a'){
    
    //找到一个字母 
					   	  index=i;break;
					   }
				}
					//左边
					for(int i=index-1;i>=0;i--){
    
    
						  if(vowel(s[i+1])&&s[i]=='?'){
    
    
						  	  ans*=20;s[i]='z';
						  }else if(!vowel(s[i+1])&&s[i]=='?'){
    
    
						  	  ans*=6;s[i]='a';
						  }
					} 
					//右边
					for(int i=index+1;i<s.length();i++){
    
    
						   if(vowel(s[i-1])&&s[i]=='?'){
    
    
						  	  ans*=20;s[i]='z';//z表示辅音,表示这个位置已经放了一个辅音了
						  }else if(!vowel(s[i-1])&&s[i]=='?'){
    
    
						  	  ans*=6;s[i]='a';//a表示元音,表示这个位置已经放了一个元音了
						 
						  }
					}
					int f2=0;
				for(int i=0;i<s.length()-1;i++){
    
    
					  if((vowel(s[i])&&vowel(s[i+1]))||(!vowel(s[i])&&!vowel(s[i+1]))){
    
    //检查相邻的是不是都是元音或者辅音
					  	  f2=1;break;
					  }
				}
				if(f2)  printf("String #%d: 0\n",g++);
				else  printf("String #%d: %lld\n",g++,ans);
			}
		}
		puts("");
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_44555205/article/details/104558719