LightOJ 1051 Good or Bad(线性)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1051

题意:给一个字符串,若串中含有连续至少3个元音字母或者连续至少5个辅音字母,则定义这个串的性质为BAD;

但是,串中有的字符是问号,问号可以被替代为任何字母。若所有问号不管替代为什么串都是BAD,则串最终为BAD;

若所有问号不管替代为什么串都不是BAD,则串最终为GOOD;若被替代后有的是BAD有的是GOOD,则串最后为MIXED。

思路:设n为字符串长度,存储在s[1]到s[n],定义p[i]表示字串s[1]到s[i],也就是p[i]是长度为i的前缀。f1[i][j]=1表示串p[i]可以以j个元音字母结尾;f2[i][j]表示串p[i]可以以j个辅音字母结尾。则可得到如下转移式:

(1)f1[i-1][j]=1,则若s[i]为元音或问号,f1[i][j+1]=1;若s[i] 为辅音或者问号,则f2[i][1]=1;

(2)f2[i-1][j]=1,则若s[i]为辅音或问号,f2[i][j+1]=1;若s[i] 为元音或者问号,则f1[i][1]=1。

最后扫描一遍,若出现f1[i][3]==1或者f2[i][5]==2,则串有可能为BAD,若f1[n][0]、f1[n][1]、f1[n][2]、f2[n][0]、f2[n][1]、f2[n][2]、f2[n][3]、f2[n][4]中有一个为1,则串有可能为GOOD。若既有那个为BAD又有可能为GOOD,则为MIXED。

View Code
 1 #include <iostream>

 2 #include <cstdio>

 3 #include <cstring>

 4 using namespace std;

 5 

 6 int C,num=0;

 7 int n,a[55],f1[55][4],f2[55][6];

 8 char s[55];

 9 

10 int OK(char x)

11 {

12     return x=='A'||x=='E'||x=='I'||x=='O'||x=='U';

13 }

14 

15 void DP()

16 {

17     int i,j;

18     memset(f1,0,sizeof(f1));

19     memset(f2,0,sizeof(f2));

20     f1[0][0]=f2[0][0]=1;

21     for(i=1;i<=n;i++)

22     {

23         for(j=0;j<=2;j++) if(f1[i-1][j])

24         {

25             if(a[i]==2||a[i]==1) f2[i][1]=1;

26             if(a[i]==2||a[i]==0) f1[i][j+1]=1;

27         }

28         for(j=0;j<=4;j++) if(f2[i-1][j])

29         {

30             if(a[i]==2||a[i]==0) f1[i][1]=1;

31             if(a[i]==2||a[i]==1) f2[i][j+1]=1;

32         }

33     }

34     int bad=0,good=0;

35     for(i=0;i<=2;i++) if(f1[n][i]) good=1;

36     for(i=0;i<=4;i++) if(f2[n][i]) good=1;

37     for(i=1;i<=n;i++) if(f1[i][3]||f2[i][5]) bad=1;

38     if(good&&bad) puts("MIXED");

39     else if(good) puts("GOOD");

40     else puts("BAD");

41 }

42 

43 int main()

44 {

45     for(scanf("%d",&C);C--;)

46     {

47         scanf("%s",s+1);

48         n=strlen(s+1);

49         int i;

50         for(i=1;i<=n;i++)

51         {

52             if(s[i]=='?') a[i]=2;

53             else if(OK(s[i])) a[i]=0;

54             else a[i]=1;

55         }

56         printf("Case %d: ",++num);

57         DP();

58     }

59     return 0;

60 }

 

 

 1 #include <iostream>

 2 #include <cstdio>

 3 #include <cstring>

 4 using namespace std;

 5 

 6 struct node

 7 {

 8     int v,next;

 9 };

10 

11 node edges[10000];

12 int head[105],e;

13 int n;

14 int dfn[105],low[105],ID,p[105],cut[105];

15 

16 

17 void init()

18 {

19     memset(head,-1,sizeof(head));

20     e=0;

21     ID=0;

22     memset(cut,0,sizeof(cut));

23     memset(dfn,0,sizeof(dfn));

24 }

25 

26 void Add(int u,int v)

27 {

28     edges[e].v=v;

29     edges[e].next=head[u];

30     head[u]=e++;

31 }

32 

33 void DFS(int u,int pre)

34 {

35     ID++;

36     dfn[u]=low[u]=ID;

37     p[u]=pre;

38     int i,v;

39     for(i=head[u];i!=-1;i=edges[i].next)

40     {

41         v=edges[i].v;

42         if(!dfn[v])

43         {

44             DFS(v,u);

45             low[u]=min(low[u],low[v]);

46         }

47         else

48         {

49             low[u]=min(low[u],dfn[v]);

50         }

51     }

52 }

53 

54 int main()

55 {

56     while(scanf("%d",&n),n)

57     {

58         init();

59         int i,u,v;

60         while(scanf("%d",&u),u)

61         {

62             while(getchar()!='\n')

63             {

64                 scanf("%d",&v);

65                 Add(u,v);

66                 Add(v,u);

67             }

68         }

69         DFS(1,-1);

70         int ans=0,x=0;

71         for(v=2;v<=n;v++)

72         {

73             u=p[v];

74             if(u==1) x++;

75             else if(dfn[u]<=low[v]) cut[u]=1;

76         }

77         if(x>1) cut[1]=1;

78         for(i=1;i<=n;i++) ans+=cut[i];

79         printf("%d\n",ans);

80     }

81     return 0;

82 }

你可能感兴趣的:(Go)