lightoj1051 Good and Bad (dp)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1051
题目大意:给你一个字符串,只包含大写字母和‘?’,如果字符串中出现了连续三个以上的元音字母或者连续五个以上的辅音字母,则这个字符串是bad,不然就是good.
‘?’号可以替换任意字母。替换以后如果既可以出现连续三个以上的元音字母或者连续五个以上的辅音字母,也可以不出现,则输出Mixed.
算法思路(参考别人的):这个地方出现不含‘?’的连续三个以上的元音字母或者连续五个以上的辅音字母则为BAD, 如果含‘?’,则看替换后的情况。具体看代码。
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int main() { //freopen("E:\\acm\\input.txt","r",stdin); int T; cin>>T; bool flag[27] = {0}; flag[0]=flag[4]=flag[8]=flag[14]=flag[20]=1; for(int cas=1; cas<=T; cas++) { char s[55]; bool dp[2][4][6] = {0}; //dp[][i][j] 表示到某一位是前面有i个元音,j个辅音相连。前面的一维用于dp前后递推 scanf("%s",s+1); int n = strlen(s+1); bool badflag,goodflag; badflag = goodflag = 0; dp[0][0][0] = true; for(int i=1; i<=n; i++) { memset(dp[i%2],0,sizeof(dp[i%2])); for(int j=0; j<3; j++) //前面元音个数为j的情况。 { if(!dp[(i+1)%2][j][0]) continue; if(s[i] == '?') dp[i%2][j+1][0] = dp[i%2][0][1] = 1; else if(flag[s[i]-'A']) dp[i%2][j+1][0] = 1; else dp[i%2][0][1] = 1; } for(int j=0; j<5; j++) //前面辅音个数为j的情况。 { if(!dp[(i+1)%2][0][j]) continue; if(s[i] == '?') dp[i%2][0][j+1] = dp[i%2][1][0] = 1; else if(flag[s[i]-'A']) dp[i%2][1][0] = 1; else dp[i%2][0][j+1] = 1; } if(dp[i%2][3][0] || dp[i%2][0][5]) badflag = true; } for(int i=0;i<3;i++) if(dp[n%2][i][0]) goodflag = true; for(int i=0;i<5;i++) if(dp[n%2][0][i]) goodflag = true; printf("Case %d: ",cas); if(goodflag && badflag) printf("MIXED\n"); else if(badflag) printf("BAD\n"); else printf("GOOD\n"); } }