洛谷 1019.单词接龙

这道题用的搜索,也就是DFS,但是有一点难度,虽然说是对于搜索的知识点的考察,但是对于编程者的编程模拟能力和分析能力会有比较大的要求。

思路:首先我们审题,会注意到以下几点:

1.单词后面相同的部分和另一个单词前面相同的部分可以接在一块,并不是直接接上,而是重合的地方合并了;

2.每个单词还不止用一次,每个单词至多用2次。

那么,我们纯靠DFS肯定不会有什么效果的。DFS要搜索的话也是有目的的搜索的,但是上面的问题有很多,我们需要逐个处理完才能够比较明确的枚举。

我们想,如果说每个单词需要不多于2次使用,我们是不是需要记录每个单词使用的次数呢?这是一点,可以定义used数组进行记录每一个单词的使用次数,这里输入字符我们就用string,因为这样会很方便的知道多个字符串的序号是什么。

既然说是相同的部分不能重复接上,那么我们会想到一个string函数中的功能:substr,这个东西能够定义从某一个字符的位置开始,从后面连上它本身能够连接多少字符,这是个很方便的运用。我们就运用这个进行接上单词。

但是还有一个问题:我们需要怎么判断每个单词到底能不能连接呢?

这样就需要有一定的刷题经验了,我们可以用一个数组cnt[][]的二维数组表示第i个单词后面与第j个单词卡面重合的个数是多少,这样既能够记录这两个单词到底能不能接上,而且还能知道个数有多少个!这样就很方便了。

解决完上面这几个问题,还有一点需要知道:怎么接上单词才能达到最长呢?我们在接上单词的过程中,明显一个特点就是重合的字符少了,自然接上的单词长度就长了,这就是结论,当我们遍历的时候,一旦找到可以重合的单词就直接认定这就是最长的,也就是所谓的重合的越少越好。

预处理结束了,我们需要开始dfs搜索了,在我们搜索的时候需要遍历全部的单词,知道哪个单词的首位与所给出的字母相同,在这个单词的基础上进行搜索,dfs函数定义两个变量,一个就是单词接龙的第一个字符串,第二个变量就是对应的这个字符串在刚刚定义的编号是多少。

写DFS时,第一件事就是把这个将要接上单词的单词的使用个数+1,然后再去遍历其他单词,判断条件就是能否接上,这个能接上的单词使用次数超过2了没有,然后接上继续搜索。

上代码:

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<cmath> 
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<sstream>
#include<map>
#include<limits.h>
#include<set>
#define MAX 30
#define _for(i,a,b) for(int i=a;i<(b);i++)
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;

LL n, m, counts, num;
string s[MAX];
int cnt[MAX][MAX];
int used[MAX];
void dfs(string haha, int u) {
    used[u] ++;
    counts = max(counts, (LL)haha.size());
    for (int i = 0; i < n; i++) {
        if (cnt[u][i] && used[i] < 2) {
            dfs(haha + s[i].substr(cnt[u][i]), i);
        }
    }
    used[u]--;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> s[i];
    }
    char word;
    cin >> word;
    //下面的操作都是对于各个单词的预处理,也就是对于单词能不能接上的判断,能接上的话重合个数是多少进行处理操作。
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            string a = s[i];
            string b = s[j];
            for (int k = 1; k < min(a.size(), b.size()); k++) {
                if (a.substr(a.size() - k, k) == b.substr(0, k)) {
                    cnt[i][j] = k;
                    break;//重合的越少越好,这样才能保证接龙的数列是最长的长度.
                }
            }
        }
    }
    for (int i = 0; i < n; i++) {
        if (s[i][0] == word) {
            dfs(s[i], i);
        }
    }
    cout << counts << endl;
    return 0;
}
相关推荐
武子康6 分钟前
大数据-212 数据挖掘 机器学习理论 - 无监督学习算法 KMeans 基本原理 簇内误差平方和
大数据·人工智能·学习·算法·机器学习·数据挖掘
passer__jw76735 分钟前
【LeetCode】【算法】283. 移动零
数据结构·算法·leetcode
Ocean☾41 分钟前
前端基础-html-注册界面
前端·算法·html
顶呱呱程序1 小时前
2-143 基于matlab-GUI的脉冲响应不变法实现音频滤波功能
算法·matlab·音视频·matlab-gui·音频滤波·脉冲响应不变法
Tianyanxiao1 小时前
如何利用探商宝精准营销,抓住行业机遇——以AI技术与大数据推动企业信息精准筛选
大数据·人工智能·科技·数据分析·深度优先·零售
爱吃生蚝的于勒1 小时前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
羊小猪~~1 小时前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
王哈哈^_^2 小时前
【数据集】【YOLO】【VOC】目标检测数据集,查找数据集,yolo目标检测算法详细实战训练步骤!
人工智能·深度学习·算法·yolo·目标检测·计算机视觉·pyqt
星沁城2 小时前
240. 搜索二维矩阵 II
java·线性代数·算法·leetcode·矩阵
脉牛杂德2 小时前
多项式加法——C语言
数据结构·c++·算法