H - Mr. Panda and Birthday Song Gym - 101775H

题意:
给你一个长度不大于1e6的字符串,由'a'-'z'或‘?’组成,且‘?’可转化为任意小写字母。和两个数x,y。

现在有两个条件:

  1. 字符串中存在任意一个长度为x的子串均为元音,或存在任意一个长度为y的子串均为子串。

  2. 字符串中所有的任意一个长度为x的子串不都是元音,且存在任意一个长度为y的子串不都是辅音。

如果同时满足条件(1)(2),则输出SURPRISE;
如果只满足(1),则输出(DISLIKE);
如果只满足(2),则输出(LIKE)。

思路
对于方案(1)
我们遍历一遍整个字符串,在‘?’的条件下,默认将元音和辅音的连续数都+1,并记录最大值判断即可。

对于方案(2)
首先我们可以判断,因为要求任意一个连续的元音/辅音小于x/y,因此我们考虑要使得他们连续的尽可能小。

因此我们考虑用dp对此进行维护。我们设dp[i][0/1],(0代表元音,1代表辅音)为位于第i号的结点时最小的连续的元音/辅音的个数。

对于某个位置的字符倘若为元音,倘若之前的状态为连续元音,则此需要将连续元音的数量+1;而倘若之前的状态为连续辅音,则此时需要将连续元音的数量重新置为1。

对于某个位置的字符为辅音的情况同理。

而对于某个位置为‘?’的情况如果之前的状态为连续的元音,则此时可以将辅音清零;如果之前的状态为连续的辅音,则此时可以将元音清零。之后只需要不断维护他们的最小值即可。倘若发现在某一个状态下,连续元音数超过x,连续辅音数超过y,则证明不满足条件(2)。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
const int N =1e6+10;
const int M=1000000007;
int n,m,k;
int TT=1;
int dp[N][3];
bool judge(char c){
    if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u')
        return 1;
    else return 0;
}
void slove()
{
    string s;cin>>s;
    n=s.length();
    int a, b; cin>>a>>b;
    string ans;
    int flag=0;
    int cnt1=0,cnt2=0;
    for(int i=0;i<n;i++){
        if(s[i]=='?'){
            cnt1++,cnt2++;
        }else{
            if(judge(s[i])) cnt1++,cnt2=0;
            else cnt2++,cnt1=0;
        }

        if(cnt1>=a || cnt2>=b){
            flag=1;
            break;
        }
    }
   int flag2=1;
   memset(dp,0x3f,sizeof dp);
    dp[0][0]=dp[0][1]=0;
    for(int i=1;i<=n;i++){
        if(s[i-1]=='?'){
          if(dp[i-1][0]<a) {
                dp[i][0]=dp[i-1][0]+1;
                dp[i][1]=1;
            }
            if(dp[i-1][1]<b){
                dp[i][1]=min(dp[i][1],dp[i-1][1]+1);
                dp[i][0]=1;
            }
        }else{
       
             if(judge(s[i-1])){
                dp[i][0]=dp[i-1][0]+1;
                if(dp[i-1][1]<b) dp[i][0]=1;
            }
            else{
                dp[i][1]=dp[i-1][1]+1;
                if(dp[i-1][0]<a) dp[i][1]=1;
            }
        }
     
        if(dp[i][0]>=a&&dp[i][1]>=b){
                flag2=0;
                break;
            }

    }
    
    //cout<<flag<<" "<<flag2<<endl;
    if(flag &&flag2)  ans="SURPRISE";
    if(flag && flag2==0) ans="DISLIKE";
    if(flag==0 &&flag2) ans="LIKE";
    cout<<"Case #"<<TT++<<": "<<ans<<endl;

}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--)
        slove();
    return 0;
}

————————————————
版权声明:本文为CSDN博主「Chen_Jr_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_39453270/article/details/83831968

posted @ 2022-08-30 22:09  kingwzun  阅读(32)  评论(0编辑  收藏  举报