PKU 2250 Compromise

PKU 2250 Compromise

http://acm.pku.edu.cn/JudgeOnline/problem?id=2250

这个也是求最长公共字串,只是相比Common Subsequence需要记录最长公共字串的构成,此时箭头的标记就用上了,在程序中,用opt[][]存放标记,0表示朝向左上方,1表示指向上,-1表示指向左。result[][]存放当前最大字串长度。在求最优解时,顺着箭头从后向前寻找公共字串的序号,记录下来,输出即可。该算法在算法导论中有详细的讲解。

 

AC CODE

#include <iostream>

#include <cstring>

using namespace std;

#define maxline 32

#define maxwords 102

char str[maxline];

char a[maxwords][maxline];

char b[maxwords][maxline];

int maxlen[maxwords][maxwords];

int flagdir[maxwords][maxwords]; // 0为左上,1为上,-1为左

int recode[maxwords];

int main()

{

       int i,j,k,m,n,t,l;

       int sharpTimes = 0 ;i=1;j=1;

       while (scanf("%s",str)!=EOF)

       {

              if (strcmp(str,"#") == 0)

              {

                     sharpTimes++;

                     if (sharpTimes == 1)

                     {

                            continue;

                     }

              }

              if (sharpTimes == 0)

              {

                    

                     strcpy(a[i],str);

                     i++;

              }

              else if (sharpTimes == 1)

              {

                     strcpy(b[j],str);

                     j++;

              }

              else if (sharpTimes == 2)

              {

                     sharpTimes = 0;

                     int len1 = i;

                     int len2 = j;

                     //---------------------------------------------

                     memset(maxlen,0,sizeof(maxlen));

                    memset(flagdir,0,sizeof(flagdir));

                     for (i=1;i<len1;i++)

                     {

                            for (j=1;j<len2;j++)

                            {

                                   if (strcmp(a[i],b[j]) == 0)

                                   {

                                          maxlen[i][j] = maxlen[i-1][j-1] +1;

                                          flagdir[i][j] = 0;

                                   }

                                   else

                                   {

                                          int t1 = maxlen[i][j-1]; //

                                          int t2 = maxlen[i-1][j]; //

                                          if (t1 >= t2) //左大选左

                                          {

                                                 maxlen[i][j] = t1;

                                                 flagdir[i][j] = -1;

                                          }

                                          else //上大选上

                                          {

                                                 maxlen[i][j] = t2;

                                                 flagdir[i][j] = 1;

                                          }

                                   }

                            }

                     }

                     i = len1; 

                     j = len2;

                     k =0 ;

                     while (1)

                     {

                            if (i == 0 || j == 0)

                            {

                                   break;

                            }

                            if(flagdir[i][j] == 0)

                            {

                                   recode[k] = i;

                                   i--;

                                   j--;

                                   k++;

                            }

                            else if (flagdir[i][j] == -1)

                            {

                                   j--;

                            }

                            else

                            {

                                   i--;

                            }

                     }

                     for(l=k-1;l>0;l--)

                     {

                            printf("%s ",a[recode[l]]);

                     }

                     printf("%s/n",a[recode[0]]);

                     //---------------------------------------------

                     i=1;j=1;

                     memset(str,'/0',sizeof(str));

                     memset(a,'/0',sizeof(a));

                     memset(b,'/0',sizeof(b));

              }

       }

       return 0;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值