题意:
给出一个字典的单词,之后给出一个单词的序列。
输出字典中各个改变一个,删除一个或增加一个字母可以变成单词序列中的单词。
思路:刚开始想用编程之美上介绍的更改距离来解这道题,发现根本行不通,
TLE到死也过不去。干脆直接暴力搜索,字典中长度比所给单词长度大1的时候,
检查删一个能否变成所给单词,小1的话就删除1个所给单词中字母,看能否变成字典中的,
相同时就先检查是否相同再检查各删掉1个字母时能否相同。
1110ms水过去的有点惭愧。。。。但没什么优化的欲望了。
#include<iostream>
#include<Cstdio>
#include<string>
using namespace std;
char word1[10050][50],word2[100][50];
int result[10050];
int l1[10050], l2[10050];
bool dic(int num1, int num2, int length)
{
char temp[50]; int i, j, no, count;
for(i = 0; i < length; i++)
{
count = 0;
for(j = 0; j < length; j++)
{
if(j != i)
temp[count++] = word1[num1][j];
}
temp[j - 1] = '\0';
if(strcmp(temp, word2[num2]) == 0)
return true;
}
return false;
}
bool add(int num1, int num2, int length)
{
char temp[50]; int i, j, no, count;
for(i = 0; i < length; i++)
{
count = 0;
for(j = 0; j < length; j++)
{
if(j != i)
temp[count++] = word2[num2][j];
}
temp[j - 1] = '\0';
if(strcmp(temp, word1[num1]) == 0)
return true;
}
return false;
}
bool rep(int num1, int num2, int length)
{
bool flag; int i, j, no;
for(i = 0; i < length; i++)
{
flag = true;
for(j = 0; j < length; j++)
{
if(i != j && word1[num1][j] != word2[num2][j])
{
flag = false;
break;
}
}
if(flag)
return true;
}
return false;
}
int main()
{
int i = 0, j = 0, k, count;
int length1, length2;
bool flag;
while(1)
{
cin >> word1[i];
l1[i] = strlen(word1[i]);
if(word1[i][0] == '#')
{
length1 = i;
break;
}
i++;
}
while(1)
{
cin >> word2[j];
if(word2[j][0] == '#')
{
length2 = j;
break;
}
l2[j] = strlen(word2[j]);
j++;
}
for(i = 0; i < length2; i++)
{
flag = false; count = 0;
for(j = 0; j < length1; j++)
{
if(l1[j] - l2[i] == 1)
{
if(dic(j, i, l1[j]))
result[count++] = j;
}
if(l2[i] - l1[j] == 1)
{
if(add(j, i, l2[i]))
result[count++] = j;
}
if(l1[j] == l2[i])
{
if(strcmp(word1[j], word2[i]) == 0)
{
flag = true;
break;
}
if(rep(j, i, l1[j]))
result[count++] = j;
}
}
if(flag)
cout << word2[i] << " is correct" << endl;
else
{
cout << word2[i] << ":";
for(k = 0; k < count; k++)
cout << " " << word1[result[k]];
cout << endl;
}
}
return 0;
}