【luogu】p1019 单词接龙

(碎碎念:初二的时候就开始写这道题,写了几天觉得啊好烦啊就不想写就放弃了,上初三之后终于抽出时间把这个题写完了
(搜索题要我狗命(缩成一团

题目链接:

https://www.luogu.com.cn/problem/P1019

题目描述

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

输入格式

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

输出格式

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

分析

由于题目中给出的数据范围单词数n<=20很小,可以用搜索dfs去解决

按照给出的字母,我们先确定好一个单词作为开头

枚举剩下的且使用没有超过两次的单词

对于每一个单词再枚举他的与前面单词相接位数并判断是否可行(要注意一个单词并不能完全包含在另一个单词中)。

如果他可以接在前一个单词上,

就先将它接入后增加的位数累加进最后的答案中,再去搜索下一个可以接上的单词。

边界状态:

当一个单词后无法再接入任何一个单词

我们就把答案与之前得到的最大答案进行比较取两者中最大值。

AC Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
int read(){
    int a = 0,f = 0;char p = getchar();
    while(!isdigit(p)){f|=p=='-';p = getchar();}
    while(isdigit(p)){a = (a<<3) + (a<<1) + (p^48);p = getchar();}
    return f?-a:a;
}
char c[25][100];//存单词
int ans;//记录每一种情况的答案
int flag[10000];//标记这个单词已经用过次数
int Ans,n; //统计最终的答案 读入单词个数
bool Flag = 0;//判断一个单词后面是否还可以继续接入单词
void dfs(int x){//dfs!
    Flag = 0;
    for(int i = 1;i <= n;i ++){//尝试把i接在x的后面
        if(flag[i] == 2)continue;
        int leni = strlen(c[i]),lenx = strlen(c[x]);//记录两个单词长度
        int cd = min(leni,lenx)-1;//最多能接在一起的长度为两个单词长度最小值-1
        int cd1,tot;
        int jl = 1;//记录我们想要接入几位
        while(jl <= cd){
            cd1 = jl,tot = 0;
            //int now = 0;
            while(cd1){//目前判断到的位置
                if(c[x][lenx-cd1] != c[i][jl-cd1])break;
                else tot++;
                cd1--;
            }
            if(tot == jl)break;//两个可以接在一起
            jl++;
        }
        if(tot == jl && tot != 0){//记录下来并且去搜索下一个
            //cout<<x<<" "<<i<<" "<<tot<<endl;
            Flag = 1;
            ans += (leni-jl);
            flag[i] ++;
            dfs(i);
            ans -= (leni-jl);
            flag[i] --;
        }
    }
    if(Flag == 0){//后面什么也没法接的时候 

        Ans = max(ans,Ans);
    }
}
int main(){
    n = read();
    for(int i = 1;i <= n;i++)
        scanf("%s",&c[i]);

    char a;
    cin >> a;
    for(int i = 1;i <= n;i++){
        if(c[i][0] == a){
            //cout<<c[i]<<endl;
            flag[i]++;
            ans = strlen(c[i]);
            dfs(i);
        }
    }
    cout << Ans;
}

注意(不过可能也就我这么憨憨才会错的一个地方)

我们在枚举他可以接入的位数时,应该从小到大进行枚举,在能让两个单词相接的情况下,让相接的部分尽可能的小

比如:
abababab和abababc

如果我们从大到小枚举它可以接入的部分那么最后相接就会变为

ababababc 有9位

但我们从小到大枚举得到的才是最长的情况

ababababababc 有13位

好了好了没了没了别看了

原文地址:https://www.cnblogs.com/huixinxinw/p/12183210.html

时间: 2024-11-11 21:28:47

【luogu】p1019 单词接龙的相关文章

luogu P1019 单词接龙

一道深搜题 应该很早就做然而并没有 这跟成语接龙一点也不像不能为所欲为 然后需要注意一下 相邻的两部分不能存在包含关系就是说如果存在包含关系,就不能标记为使用过. 每个单词最多出现两次 这样提前先预处理一下每两个单词之间的重复部分 用sam[i][j]表示第i个单词后接第j个单词的重叠的部分 然后dfs,记得用vis标记一下该单词使用过几次 #include<cstdio> #include<iostream> #define sev en using namespace std;

luogu 1019 单词接龙 dfs细节

P1019 单词接龙 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连. 输入输出格式 输入格式: 输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,

洛谷P1019 单词接龙

P1019 单词接龙 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连. 输入输出格式 输入格式: 输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,

洛谷P1019单词接龙 搜索

洛谷P1019 单词接龙 这道题目 我用的是搜索 应为起点已经确认了,那就从这开始搜索,如果能接上去就接上去,回溯一下需要注意的就是一些细节问题,比方说不能被另一个单词完全覆盖等等 以及字符串是从零开始的问题 1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdlib> 5 #include <string> 6 #include <a

洛谷 P1019 单词接龙

P1019 单词接龙 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连. 输入输出格式 输入格式: 输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,

洛谷——P1019 单词接龙(NOIP2000 T3)

https://www.luogu.org/problem/show?pid=1019#sub 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连. 输入输出格式 输入格式: 输入的第一

洛谷P1019——单词接龙(DFS暴力搜索)

https://www.luogu.org/problem/show?pid=1019#sub 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的"龙"(每个单词都最多在"龙"中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连. 输入输

洛谷 P1019 单词接龙 深搜

题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的"龙"(每个单词都最多在"龙"中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连. 输入输出格式 输入格式: 输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每

P1019 单词接龙

题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连. 输入输出格式 输入格式: 输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单