洛谷 P1019 单词接龙(尚贤)

在这里插入图片描述

题目传送门

复杂模拟题
AC代码(有自测注释)

#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#define SIZE 20 + 10
#define INF 0x3f3f3f3f * 2;
using namespace std;
int n, len = -1, ans = -INF;
string str[SIZE];
int vis[SIZE];
vector<string> s1, s2;

void dfs(const string &);
int f1(const string &, const string &);

int main() {
	freopen("cpp.in", "r", stdin);
	freopen("cpp.out", "w", stdout);
//	cout << f1("asdfasdfat", "at") << endl;
//	return 0;
	scanf("%d", &n);
	for (int i = 0; i < n; ++i) {
		cin >> str[i];
	}
	string ch;
	cin >> ch;
	dfs(ch);
	//用来输出最后要接在一起的字符串)
//	for (int i = 0; i < s2.size(); ++i) {
//		cout << s2[i] << " ";
//	}
//	cout << endl;
	printf("%d\n", ans);
	return 0;
}

void dfs(const string &temp) {
//	ans = max(len, ans);
	if (ans < len) {
		while (s2.size()) {
			s2.pop_back();
		}
		for (int i = 0; i < s1.size(); ++i) {
			s2.push_back(s1[i]);
		}
		ans = len;
	}
	for (int i = 0; i < n; ++i) {
		if (vis[i] <= 1) {
			int t = f1(temp, str[i]);
//			cout << temp << " " << str[i] << " " << t << " # " << len << " # ";
			if ((len == -1 && str[i][0] == temp[0]) || t > 0) {
				len = ((len == -1) ? str[i].size() : len + str[i].size() - t);
				++vis[i];
				s1.push_back(str[i]);
//				cout << len << endl;
				dfs(str[i]);
				s1.pop_back();
				--vis[i];
				len = ((len == str[i].size()) ? -1 : len + t - str[i].size());
			}
		}
	}
}
int f1(const string &a, const string &b) {
	for (int i = 1; i < min(a.size(), b.size()); ++i) {
		int temp1 = a.size() - i, temp2 = 0;
//		printf("i = %d, temp1 = %d, temp2 = %d\n", i, temp1, temp2);
		if (a[temp1] != b[temp2]) {
			continue;
		}
		while (a[temp1] == b[temp2] && temp2 < i) {
//			cout << temp1 << " " << temp2 << " # ";
			++temp1;
			++temp2;
//			cout << temp1 << " " << temp2 << endl;
		}
		if (temp2 == i) {
			return i;
		}
	}
	return 0;
}

AC代码(无自测注释)

#include <iostream>
#include <cstdio>
#include <string>
#define SIZE 20 + 10
using namespace std;
int n, len = -1, ans = 0, vis[SIZE];
string str[SIZE];

void dfs(const string &);
int f1(const string &, const string &);

int main() {
	freopen("cpp.in", "r", stdin);
	freopen("cpp.out", "w", stdout);
	scanf("%d", &n);
	for (int i = 0; i < n; ++i) {
		cin >> str[i];
	}
	string ch;
	cin >> ch;
	dfs(ch);
	printf("%d\n", ans);
	return 0;
}

void dfs(const string &temp) {
	ans = max(len, ans);
	for (int i = 0; i < n; ++i) {
		if (vis[i] <= 1) {
			int t = f1(temp, str[i]);
			if ((len == -1 && str[i][0] == temp[0]) || t > 0) {
				len = ((len == -1) ? str[i].size() : (len + str[i].size() - t));
				++vis[i];
				dfs(str[i]);
				--vis[i];
				len = ((len == str[i].size()) ? -1 : (len + t - str[i].size()));
			}
		}
	}
}
int f1(const string &a, const string &b) {
	for (int i = 1; i < min(a.size(), b.size()); ++i) {
		int temp1 = a.size() - i, temp2 = 0;
		if (a[temp1] != b[temp2]) {
			continue;
		}
		while (a[temp1] == b[temp2] && temp2 < i) {
			++temp1, ++temp2;
		}
		if (temp2 == i) {
			return i;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值