如果不论我们怎么替换,这个字符串都会包含连续的 3 个元音字符或 5 个连续的辅音的话,这个串就是一个 bad 串。
如果不论我们怎么替换,这个字符串都不会包含连续的 3 个元音字符或 5 个连续的辅音的话,这个串就是一个 good 串。
否则是一个 mixed 串,
现在问我们 s 是那个类型的串?
思路
设 f1 [i][j] 表示在 i 个位置为结尾,有 j 个连续元音字符的这种情况是否存在,
设 f2 [i][j] 表示在 i 个位置为结尾,有 j 个连续辅音字符的这种情况是否存在,
之后按 s [i] 位置字符类型进行转移就行了,
如果 s [i] 是 ?
如果 s [i] 是元音
如果 s [i] 是辅音
代码
#include<bits/stdc++.h>
using namespace std;#definedbdouble#definelllonglong#definescscanf#defineprprintf#definefifirst#definesesecond#definepbpush_back#definem_pmake_pair#definePirpair<int,int>#defineinf0x3f3f3f3f#defineINF0x3f3f3f3f3f3f3f3f/*==========ACMer===========*/constint N =55;char s[N];int f1[N][N], f2[N][N];//f1[i][j] 表示前 i 个位置有 j 个元音的情况是否存在//f2[i][j] 表示前 i 个位置有 j 个元音的情况是否存在inttrans(char ch){if(ch =='?')return2;return(ch =='A'|| ch =='E'|| ch =='I'|| ch =='O'|| ch =='U');}intmain(){int T, cas =1;sc("%d",&T);while(T --){sc("%s", s +1);int n =strlen(s +1);for(int i =1; i <= n; i ++) s[i]=trans(s[i]);memset(f1,0,sizeof f1);memset(f2,0,sizeof f2);
f1[0][0]= f2[0][0]=1;for(int i =1; i <= n; i ++){for(int j =0; j <=2; j ++){if(f1[i -1][j]){if(s[i]==2|| s[i]==0)
f2[i][1]=1;if(s[i]==2|| s[i]==1)
f1[i][j +1]=1;}}for(int j =0; j <=4; j ++){if(f2[i -1][j]){if(s[i]==2|| s[i]==1)
f1[i][1]=1;if(s[i]==2|| s[i]==0)
f2[i][j +1]=1;}}}
bool good =0, bad =0;for(int i =0; i <=2; i ++)if(f1[n][i]) good =1;//对于最后一个元素只要某个 f1[n][i] 为 1 (而这个 1 是从n-1位置的的某个位置j 状态f1[n - 1][]转移过来的....同理 f1[n-1][1] 为真也是从前 n-2 的某个合法状态转移来的),那么这个串一定存在在一个方案使这个串为goodfor(int i =0; i <=4; i ++)if(f2[n][i]) good =1;//与上同理for(int i =1; i <= n; i ++){if(f1[i][3]|| f2[i][5])//只要有一个 bad 就存在一种方案为 bad
bad =1;}pr("Case %d: ", cas ++);if(good && bad)pr("MIXED\n");elseif(good)pr("GOOD\n");elsepr("BAD\n");}return0;}