Double-ended Strings(双头字符串)
链接
CF_1506C Double-ended Strings(双头字符串)
Description
if
∣
a
∣
>
0
|a|>0
∣a∣>0 (the length of the string
a
a
a is greater than zero), delete the first character of the string
a
a
a, that is, replace
a
a
a with
a
2
a
3
…
a
n
a2a3…an
a2a3…an;
if
∣
a
∣
>
0
|a|>0
∣a∣>0, delete the last character of the string
a
a
a, that is, replace
a
a
a with
a
1
a
2
…
a
n
−
1
a1a2…an−1
a1a2…an−1;
if
∣
b
∣
>
0
|b|>0
∣b∣>0 (the length of the string
b
b
b is greater than zero), delete the first character of the string
b
b
b, that is, replace
b
b
b with
b
2
b
3
…
b
n
b2b3…bn
b2b3…bn;
if
∣
b
∣
>
0
|b|>0
∣b∣>0, delete the last character of the string
b
b
b, that is, replace
b
b
b with
b
1
b
2
…
b
n
−
1
b1b2…bn−1
b1b2…bn−1.
Note that after each of the operations, the string a or b may become empty.
For example, if a = "hello" a=\texttt "\texttt h\texttt e\texttt l\texttt l\texttt o\texttt " a="hello" and b = "icpc" b=\texttt "\texttt i\texttt c\texttt p\texttt c\texttt " b="icpc", then you can apply the following sequence of operations:
delete the first character of the string
a
⇒
a
=
"ello"
a ⇒ a=\texttt "\texttt e\texttt l\texttt l\texttt o\texttt "
a⇒a="ello" and
b
=
"icpc"
b=\texttt "\texttt i\texttt c\texttt p\texttt c\texttt "
b="icpc";
delete the first character of the string
b
⇒
a
=
"ello"
b ⇒ a=\texttt "\texttt e\texttt l\texttt l\texttt o\texttt "
b⇒a="ello" and
b
=
"cpc"
b=\texttt "\texttt c\texttt p\texttt c\texttt "
b="cpc";
delete the first character of the string
b
⇒
a
=
"ello"
b ⇒ a=\texttt "\texttt e\texttt l\texttt l\texttt o\texttt "
b⇒a="ello" and
b
=
"pc"
b=\texttt "\texttt p\texttt c\texttt "
b="pc";
delete the last character of the string
a
⇒
a
=
"ell"
a ⇒ a=\texttt "\texttt e\texttt l\texttt l\texttt "
a⇒a="ell" and
b
=
"pc"
b=\texttt "\texttt p\texttt c\texttt "
b="pc";
delete the last character of the string
b
⇒
a
=
"ell"
b ⇒ a=\texttt "\texttt e\texttt l\texttt l\texttt "
b⇒a="ell" and
b
=
"p"
b=\texttt "\texttt p\texttt "
b="p".
For the given strings
a
a
a and
b
b
b, find the minimum number of operations for which you can make the strings
a
a
a and
b
b
b equal. Note that empty strings are also equal.
Input
The first line contains a single integer t ( 1 ≤ t ≤ 100 ) t (1≤t≤100) t(1≤t≤100). Then t t t test cases follow.
The first line of each test case contains the string a ( 1 ≤ ∣ a ∣ ≤ 20 ) a (1≤|a|≤20) a(1≤∣a∣≤20), consisting of lowercase Latin letters.
The second line of each test case contains the string b ( 1 ≤ ∣ b ∣ ≤ 20 ) b (1≤|b|≤20) b(1≤∣b∣≤20), consisting of lowercase Latin letters.
Output
For each test case, output the minimum number of operations that can make the strings a a a and b b b equal.
Example
Onput
5
a
a
abcd
bc
hello
codeforces
hello
helo
dhjakjsnasjhfksafasd
adjsnasjhfksvdafdser
Output
0
2
13
3
20
解析
实际上本题求的就是最长公共子串的长度。
我们可以用 f i , j f_{i,j} fi,j 来表示字符串 a a a 的第 i i i 个字符与字符串 b b b 的第 j j j 个字符是否相等,若相等, f i , j = 1 f_{i,j}=1 fi,j=1,若不等, f i , j = 0 f_{i,j}=0 fi,j=0。最后我们再查找 f f f 的中值为 1 1 1 的最长的对角线的长度即为答案。
还有更简单的方程:
f
i
,
j
=
f
i
−
1
,
j
−
1
+
1
f_{i,j}=f_{i-1,j-1}+1
fi,j=fi−1,j−1+1
这样可以在计算 f i , j f_{i,j} fi,j 的同时就求出答案。
代码
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,f[21][21],ans;
string a,b;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
ans=0;
memset(f,0,sizeof(f));
cin>>a>>b;
for(int j=0;j<a.size();j++)
for(int k=0;k<b.size();k++)
if(a[j]==b[k])
{
f[j+1][k+1]=1+f[j][k];
ans=max(ans,f[j+1][k+1]);
}
ans=a.size()+b.size()-2*ans;
printf("%d\n",ans);
}
return 0;
}