洛谷p1019单词接龙-dfs

本文深入解析洛谷P1019题目,介绍了一种通过递归搜索和字符串重叠检测来求解最大字符串组合长度的算法。文章详细解释了如何使用C++的string成员函数substr进行字符串截取,以及如何通过标记数组控制字符串的重复使用,确保每个字符串最多被使用两次。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://www.luogu.com.cn/problem/P1019
这道题好难想,刚开始就字符拼接这块写了一大堆,写完搜索不会写了,光找两个字符串的最小重叠部分就写了好多,最后写不下去了,需要太多代码了,于是就去找大佬题解了,确实自己写繁了,梳理一下大佬的思路吧。
对所有的字符串循环,对于首字母符合条件的以这个字符串开头进行搜索,所以可能搜索不止一次。由于每个字符串最多出现2次,所以用一个标记数组记录某个字符串的使用次数,2次之后就不再使用。
在搜索函数里,难点在于最小重叠部分的寻找,大佬使用了string的成员函数substr,他可以截取字符串的一部分,单参数截取该位置到尾的字符串,双参数前一部分是截取位置,后一部分是截取长度。如果还有疑问可以自己搜一搜。
由于只需要求出最小重叠部分(因为最小重叠才能确保最大长度),所以从上一个字符串的尾部和当前字符串的头部开始检测,如果截取的字符串相等,那就可以拼接,继续下一步搜索。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <queue>
#include <iomanip>
using namespace std;

string arr[100];
int vis[100];
char head;

int n,ans;


void dfs(string x,int len) {//x表示上一次连接的字符串,len表示总的字符串长度
	ans = max(ans, len);
	for (int i = 0; i < n; i++) {
		int la = x.length(), lb = arr[i].length();
		int p = 1;
		while (p < min(la, lb)) {
			if (x.substr(la - p) == arr[i].substr(0, p) && vis[i] < 2) {
				vis[i]++;
				dfs(arr[i], len + lb - p);
				vis[i]--;
			}
			p++;
		}
	}
}

int main() {
#ifdef ONLINE_JUDGE
#else
	freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
	cin >> n;
	for (int i = 0; i < n; i++)cin >> arr[i];
	cin >> head;
	for (int i = 0; i < n; i++) {//找出以head开头的字符串,符合条件的进行搜索
		if (arr[i][0] == head) {
			vis[i]++;
			dfs(arr[i], arr[i].length());
			vis[i]--;
		}
	}
	cout << ans << endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值