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;
}