单词接龙--蒟蒻解析

ops/2025/2/22 14:56:58/

我是觉得这道题目巨难,所以认真写了一篇博客,也可能是我是蒟蒻的原因吧

​​​​​​​P1019 [NOIP 2000 提高组] 单词接龙 - 洛谷https://www.luogu.com.cn/problem/P1019

题目说每个单词只能用两次,所以我们直接将这组单词复制一次,弄成两组相同的单词,然后在比较前后缀相同的东西,根据这个写了一个check函数,进行对比,并且我增加了点难度,把23位的龙打印了出来,写出来,我觉得还是很有成就感的吧!!!

 

#include<bits/stdc++.h>
using namespace std;// 全局变量声明
int n, ans;            // n: 初始字符串数量,ans: 记录最长龙的长度
char ch;               // 龙头字符要求
string s[42], str, ret;// s: 字符串数组(含副本),ret: 存储最长龙
int vis[42];           // 访问标记数组,控制每个字符串最多使用两次/* 检查两个字符串的重叠部分* s1: 已拼接的字符串* s2: 待拼接的字符串* 返回: 最大重叠长度,无重叠返回-1 */
int check(string s1, string s2) {// 从s1末尾开始尝试匹配,寻找最大重叠for (int i = s1.length() - 1; i >= 0; i--) {int len = s1.length() - i; // 当前尝试的重叠长度// 截取s1末尾len长度与s2开头len长度比较if (s1.substr(i) == s2.substr(0, len)) {return len; // 返回实际重叠长度}}return -1;
}/* 深度优先搜索构建单词龙* q: 当前拼接的字符串* dep: 递归深度(已使用的字符串数量)*/
void dfs(string q, int dep) {// 更新最长记录if (q.length() > ans) {ans = q.length();ret = q;}// 终止条件:每个字符串最多使用两次(总深度2n)if (dep > 2 * n) return;// 遍历所有字符串(包含副本)for (int i = 1; i <= 2 * n; i++) {// 第一层特殊处理:必须匹配龙头字符if (dep == 1 && !vis[i] && ch == s[i][0]) {vis[i] = 1;dfs(q + s[i], dep + 1); // 拼接新字符串vis[i] = 0;             // 回溯}// 后续层处理:需要满足重叠条件else if (dep >= 2 && !vis[i]) {int res = check(q, s[i]);if (res != -1) {        // 存在有效重叠vis[i] = 1;// 拼接时跳过重叠部分dfs(q + s[i].substr(res), dep + 1);vis[i] = 0;         // 回溯}}}
}int main() {// 输入处理cin >> n;for (int i = 1; i <= n; i++) cin >> s[i];// 创建字符串副本(允许每个字符串使用两次)for (int i = n+1; i <= 2*n; i++) s[i] = s[i - n];cin >> ch;  // 输入龙头字符dfs(str, 1); // 从空字符串开始搜索cout<<ret<<ans//以防止有人抄袭,我将这个打印出来了cout << ans; // 输出最大长度return 0;
}

 还有一种方法,就是用used标记两个数组,最多只能用两个,超过不行

#include<bits/stdc++.h>
using namespace std;
int n,ans;
string str[30];
int used[30];
int check(string a,string b) {int la = a.length();int lb = b.length();int l = min(la, lb);for (int i = 1; i < l; i++) {int flag = 1;for (int j = 0; j < i; j++) {if (a[la - i + j] != b[j])flag = 0;}if (flag)return i;}return 0;
}
void dfs(string s, int len) {ans = max(ans, len);for (int i = 1; i <= n; i++) {if (used[i] >= 2)continue;int c = check(s, str[i]);if (c > 0){used[i]++;dfs(str[i], len + str[i].length() - c);used[i]--;}}
}
int main() {cin >> n;for (int i = 1; i <= n; i++){cin >> str[i];}string S;cin >> S;dfs(' '+S, 1);cout << S << endl;cout << ans << endl;return	0;
}


http://www.ppmy.cn/ops/160530.html

相关文章

linux 安装启动zookeeper全过程及遇到的坑

1、下载安装zookeeper 参考文章&#xff1a;https://blog.csdn.net/weixin_48887095/article/details/132397448 2、启动失败 1、启动失败JAVA_HOME is not set and java could not be found in PATH 已安装 JAVA 配置了JAVA_HOME,还是报错解决方法&#xff1a;参考&#xf…

ubuntu ffmpeg 安装踩坑

ffmpeg 安装踩坑 安装命令: sudo apt update sudo apt install ffmpeg如果以上命令没有报错&#xff0c;那么恭喜你很幸运&#xff0c;可以关闭这篇文章了&#xff01; 如果跟我一样&#xff0c;遇到如下报错&#xff0c;可以接着往下看&#xff1a; 报错信息&#xff1a; …

OSPF | 理论 / 实验

注&#xff1a;本文为 “OSPF” 相关文章合辑。 本专栏已经有一些关于 OSPF 的文章&#xff0c;偶然发现本文作者对 OSPF 知识点覆盖很全面&#xff0c;特汇记一份于此。 OSPF 全网最详解&#xff08;理论及配置&#xff09; Lxyand1 于 2024-12-12 10:46:50 发布 一。简介 …

如何确定服务器是否被黑客入侵爆破

服务器被黑客入侵爆破&#xff08;如暴力破解密码或利用漏洞攻击&#xff09;是网络安全中常见的威胁之一。这类攻击可能导致数据泄露、服务中断甚至系统完全失控。本文将详细介绍如何检测服务器是否被黑客入侵爆破&#xff0c;并提供实用的代码示例和解决方案。 一、黑客入侵…

解决npm问题:错误的代理设置

错误的代理设置 npm install vue-waterfall-plugin-next npm ERR! code ECONNREFUSED npm ERR! syscall connect npm ERR! errno ECONNREFUSED npm ERR! FetchError: request to https://registry.npmmirror.com/vue-waterfall-plugin-next failed, reason: connect ECONNREFU…

AI前端开发对国际化职业发展的影响

在全球化的今天&#xff0c;前端开发人才的需求日益增长。而人工智能&#xff08;AI&#xff09;技术的快速发展&#xff0c;正深刻地改变着前端开发的模式。本文将探讨AI写代码工具如何影响前端开发者的国际化职业发展&#xff0c;并以ScriptEcho为例&#xff0c;分析其如何助…

Selenium库详解:Python实现模拟登录与反爬限制的进阶指南

一、Selenium库简介 Selenium是一个开源的自动化测试框架&#xff0c;广泛应用于Web自动化测试和爬虫开发。它支持多种编程语言&#xff08;如Python、Java、C#等&#xff09;和主流浏览器&#xff08;如Chrome、Firefox、Safari等&#xff09;。通过Selenium&#xff0c;开发…

制定产品宽高比相关标准的考量维度

制定宽高比相关标准的考量维度需从以下维度综合权衡: 功能性需求 核心场景适配:明确产品核心用途(如运输、显示、存储),确定宽高比对功能的影响权重。 物理限制:材料强度、热力学性能(如散热需求限制电子设备厚度)。 生产效率与成本 模数化设计:定义基础模数(如1…