字符串最短距离问题

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值