Question:
设有字符串X,称在X的头尾及中间插入任意多个空格后构成的新字符串为X的扩展串,如字符串X为“abcbcd”,则字符串“abcb□cd”,“□a□bcbcd□”和“abcb□cd□”都是X的扩展串,这里“□”代表空格字符。 如果A1是字符串A的扩展串,B1是字符串B的扩展串,A1与B1具有相同的长度,那么定义字符串A1与B1的距离为相应位置上的字符的距离总和,而两个非空格字符的距离定义为它们的ASCII码的差的绝对值,而空格字符与其它任意字符之间的距离为已知的定值K,空格字符与空格字符的距离为0。在字符串A、B的所有扩展串中,必定存在两个等长的扩展串A1、B1,使得A1与B1之间的距离达到最小,将这一距离定义为字符串A、B的距离。请编写程序,求出字符串A、B的距离。
Input
每组数据输入字符串A1和B1以及常数K
Output
输出字符串最短距离
Sample:
Input
cmc
snmn
2
Output
10
Analysis:
假设串A1,B1具有最短距离,那么A1[0],B1[0]只有如下三种情况:
Case 1Case 2 Case 3
A A1[0] ____ A1[0]
B ____ B1[0] B1[0]
每种情况我们需要求出后继子串的最短距离加上当前字符的距离,就得倒最短距离。
伪代码
StrDis(s[0...slen],t[0...tlen])=min{
k+StrDis(s[1...len],t[0...tlen]),
k+StrDis(s[0...len],t[1...tlen]),
abs(s[0]-t[0])+StrDis(s[1..slen],t[1..tlen])
}
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <stdlib.h>
#include <algorithm>
using namespace std;
const int Max=1050;int k,sum;
#define LL long long
#define CLR(a,b) memset(a,b,sizeof(a))
int StrDis(char *s,char *t)
{
int sum,i,temp[3];
if(s[0]=='\0'&&t[0]=='\0')
return 0;
if(s[0]!='\0'&&t[0]=='\0')
{
for(sum=0,i=0;s[i]!='\0';i++)
sum+=k;
return sum;
}
if(s[0]=='\0'&&t[0]!='\0')
{
for(sum=0,i=0;t[i]!='\0';i++)
sum+=k;
return sum;
}
temp[0]=StrDis(s+1,t)+k;
temp[1]=StrDis(s,t+1)+k;
temp[2]=StrDis(s+1,t+1)+abs(s[0]-t[0]);
sum=temp[0]<temp[1]?temp[0]:temp[1];
sum=sum<temp[2]?sum:temp[2];
return sum;
}
int main()
{
char s[Max],t[Max];
while(~scanf("%s%s%d",s,t,&k))
{
sum=0;
sum=StrDis(s,t);
cout<<sum<<endl;
}
return 0;
}