【问题描述】
麦克正如我们所知的已快乐地结婚,在上个月他胖了70磅。因为手指上的脂肪过多,使他连给他最亲密的朋友斯拉夫克写一个电子邮件都很困难。
每晚麦克都详细地描述那一天他所吃的所有东西,但有时当他只想按一次某键时往往会按了不止一次,并且他的胖手指还会碰到他不想要按的键,麦克也知道自己的手指有问题,因此他在打字的时候很小心,以确保每打一个想要的字符时误打的字符不超过3个,误打的字符可能在正确字符之前也可能在其之后。
当斯拉夫克多次收到读不懂的电子邮件后,他总是要求麦克将电子邮件发3遍,使他容易读懂一点。
编写程序,帮助斯拉夫克根据他所收到的三封电子邮件求出麦克可能写出的最长的信。
【输入文件】
输入文件包含了三行文本。每一行文本包括麦克信件的一种版本。其中所有的字符都由英文字母表中的小写字母组成并且不超过100个。
【输出文件】
输出文件中第一行即唯一的一行数据应该包含斯拉夫克根据所收到的电子邮件推测出的最长信件。你可以相信问题一定有解,但解不一定是唯一的。
【输入输出样例】
输入:
cecqbhvaiaedpibaluk
cabegviapcihlaaugck
adceevfdadaepcialaukd
输出:
cevaiaauk
分析:
就是求三个字符串的最长公共子串.
【参考程序】:
#include<fstream>
#include<cstring>
using namespace std;
const int dx[8]={0,-1,0,0,-1,-1,0,-1};//每个位置字符的取舍情况(0代表不取,-1代表不取)
const int dy[8]={0,0,-1,0,-1,0,-1,-1};
const int dz[8]={0,0,0,-1,0,-1,-1,-1};
int opt[101][101][101],dir[101][101][101];
string s1,s2,s3,ss;
int len1,len2,len3;
void print(int a,int b,int c)
{
if (dir[a][b][c]==-1) return ;
print(a+dx[dir[a][b][c]],b+dy[dir[a][b][c]],c+dz[dir[a][b][c]]);
if (dir[a][b][c]==7) ss+=s1[a];
}
void work()
{
memset(opt,0,sizeof(opt));
memset(dir,-1,sizeof(dir));
for (int i=1;i<=len1;i++)
for (int j=1;j<=len2;j++)
for (int k=1;k<=len3;k++)
if (s1[i]==s2[j] && s2[j]==s3[k])
{
opt[i][j][k]=opt[i-1][j-1][k-1]+1;
dir[i][j][k]=7;
}
else
{
int max=-100000,d;
for (int l=1;l<=6;l++)
if (opt[i+dx[l]][j+dy[l]][k+dz[l]]>max)
{
max=opt[i+dx[l]][j+dy[l]][k+dz[l]];
d=l;
}
opt[i][j][k]=max;
dir[i][j][k]=d;
}
}
int main()
{
ifstream cin("fatboy.in");
ofstream cout("fatboy.out");
cin>>s1;cin>>s2;cin>>s3;
len1=s1.length();len2=s2.length();len3=s3.length();
s1=' '+s1;s2=' '+s2;s3=' '+s3;
work();
ss="";
print(len1,len2,len3);
cout<<ss<<endl;
return 0;
}