Summary:
You will be given a string containing capital letters and 0 or more '?' question marks. You can substitute '?' with vowel or consonant. A string is considered as BAD
if it contains 3 vowels or 5 consonants in a row otherwise it is GOOD
. It is MIXED
if it can be made both good and bad by substituting '?' with consonant or vowel. You have to find whether a string is GOOD
or BAD
or MIXED
.
Observations:
- If there is no '?' question mark in string and the string contains 3 vowels or 5 consonant in a row then it is
BAD
otherwise it is GOOD
.
- If the string contains '?' then it can be
GOOD
or BAD
or MIXED
.
- If the string contains 3 vowels or 5 consonants after substituting
one or more '?'
then it is BAD
. If the string does not contain 3 vowels or 5 consonants in a row after substituting all '?' then it is GOOD
.
- If
all '?'
can be substituted in such a way that it can be GOOD
and also can be BAD
based on substituted letters in place of '?' then it is MIXED
.
You can make decision only at the positions containing '?'. You have two choices:
- Replace it by a vowel or,
- Replace it by a consonant.
Solution:
Use recursion
to solve this problem.
Iterate from first position to the last position of the string and in each position check if it contains 3 vowels or 5 consonants in a row from first position to current position.
If any position contains '?' then -
- Replace it by vowel and check if it holds the condition to be
BAD
. If holds then it is BAD
and return BAD
, else continue like this till the last position.
- Replace it by consonant and check if it holds the condition to be
BAD
. If holds then it is BAD
and return BAD
, else continue like this till the last position.
If you reach the last position of the string and does not hold the condition to be BAD
then it is GOOD
and return GOOD
.
If choice 1 and 2 both return BAD
then the string is BAD
.If both of them return GOOD
then it is GOOD
. If one of them return GOOD
and another one of them return BAD
then it is MIXED
. If any one of them return MIXED
then it is MIXED
.
It is better to keep track of the number of vowels and consonants in a row from first position to current position instead of replacing '?' every time.
Algorithm:
S
is the given string. vowel
and cons
are the number of vowels and consonants in a row.
Start from i=0
and continue till the last position of the string.
GOOD_OR_BAD(S , i , vowel , cons)
1. if vowel == 3 or cons == 5 then,
return BAD
2. if i >= s.size() then,
return GOOD
3. if s[i] == '?' then,
v = GOOD_OR_BAD(s,i+1,vowel+1,0)
c = GOOD_OR_BAD(s,i+1,0,cons+1)
4. if v!=c or v == MIXED or c == MIXED then,
return MIXED
5. else
return v
6. else if isVowel( s[i] ) == true then,
return GOOD_OR_BAD(s,i+1,vowel+1,0)
7. else
return GOOD_OR_BAD(s,i+1,0,cons+1)
This solution will cause TLE
. To reduce the time complexity apply dynamic programming
. Take a 3D array say dp
. dp[i][vowel][cons]
contains number of vowels and consonants in a row from position 0 to i
for position i
. Whenever it finds the optimal solution for position i
it stores the result and the number of vowel and consonant for which it gets optimal result in dp[i][vowel][cons]
. Later, when an optimal solution is found in dp it returns the solution.
Code(C++):
#include<bits/stdc++.h>
#define vi vector<int>
#define vvi vector<vi>
using namespace std;
bool isVowel(char c){
if(c=='A' or c=='E' or c=='I' or c=='O' or c=='U')
return true;
return false;
}
int goodBad(const string& s,int i,int vowel,int cons,vector<vvi>&dp)
{
if(vowel == 3 or cons == 5)
return 1;
if(i>=s.size())
return 0;
if(dp[i][vowel][cons]!=-1)
return dp[i][vowel][cons];
if(s[i] == '?')
{
int v = goodBad(s,i+1,vowel+1,0,dp);
int c = goodBad(s,i+1,0,cons+1,dp);
if(v!=c or v == 2 or c == 2)
return dp[i][vowel][cons] = 2;
else
return dp[i][vowel][cons] = v;
}
else if(isVowel(s[i]))
return dp[i][vowel][cons] = goodBad(s,i+1,vowel+1,0,dp);
else
return dp[i][vowel][cons] = goodBad(s,i+1,0,cons+1,dp);
}
int main()
{
vector<string>ans = {"GOOD","BAD","MIXED"};
int t,cs=1;
cin>>t;
while(t--)
{
string s;
cin>>s;
vector<vvi>dp(s.size(),vvi(s.size(),vi(s.size(),-1)));
int res = goodBad(s,0,0,0,dp);
cout<<"Case "<<cs++<<": "<<ans[res]<<endl;
}
return 0;
}
Tutorial source