luogu1019 单词接龙

http://www.elijahqi.win/archives/818
题目描述

单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连。

输入输出格式

输入格式:

输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.

输出格式:

只需输出以此字母开头的最长的“龙”的长度

输入输出样例

输入样例#1:

5
at
touch
cheat
choose
tact
a
输出样例#1:

23 (连成的“龙”为atoucheatactactouchoose)

这题当作考试然后爆0了!我感觉心态都爆炸啦,大概太弱

后来 回家认真推导一下还是能过的

考试心态不好

因为存在做两遍的情况 所以我们干脆复制一下

然后我们每次从后面做,因为只是这个字母开头,我们可能有多种情况,我们不妨都枚举下就好

我把他们的序号都记录在a数组中,方便以后使用

深搜的时候 就是简单的搜索,我看能匹配多少,然后答案我只加后面多出来的,避免重复

可以用样例考虑下,然后最后返回值的时候加上我初始串的长度就好

#include
#include
char s[44][1100];int n,a[22],cnt;
inline int max(int x,int y){
    return x>y?x:y;
}
bool flag[44];
int f(int x){
    flag[x]=true;int len1=strlen(s[x]+1);int ans1=0;
    for (int i=1;i<=2*n;++i){
        if (!flag[i]){
            int len2=strlen(s[i]+1);
            for (int z=1;z<=len2;++z){
                bool flag1=true;
                for (int j=len1-z+1;j<=len1;++j){
                    if (s[x][j]!=s[i][j-(len1-z+1)+1]) flag1=false;
                }
                if (flag1&&z!=len2) ans1=max(ans1,f(i)+len2-z);
            }
        }
    }
    flag[x]=false;
    return ans1;
}
int main(){
    freopen("1019.in","r",stdin);
    scanf("%d",&n);
    for (int i=1;i<=n;++i)scanf("%s",s[i]+1);
    char str1[2];
    scanf("%s",str1);int num;
    for (int i=1;i<=n;++i) if (str1[0]==s[i][1]) a[++cnt]=i;
    int ans=0; 
    for (int z=1;z<=cnt;++z){
        num=n;
        for (int i=1;i<=n;++i){
            int len=strlen(s[i]+1);
            if (i==a[z]) {    
                for (int j=1;j<=len;++j) s[n<<1][j]=s[i][j];
                continue;
            }++num;
            for (int j=1;j<=len;++j) s[num][j]=s[i][j];
        }
        //for (int i=1;i<=2*n;++i) printf("%s\n",s[i]+1);
        ans=max(ans,f(2*n)+strlen(s[a[z]]+1));
    }
    printf("%d",ans);
    return 0;
}

你可能感兴趣的:(搜索)