刷题日记——2024_2_26
原题链接:
题目分析
题目描述中有几个关键的点
-
可以任意选择重合部分的长度
-
重合长度必须大于等于1
-
重合长度严格小于两个串的长度
对于该题,在数据输入时有一个小技巧:把开头字母作为字符串处理c = " " + c
这样一来就能直接把它丢进dfs中,直接搜到结果。
下面说一下dfs 的思路
这里设置dfs有两个参数string x
int y
分别表示拼接后的总字符串,以及上次拼接所用的字符串的序号。
每次dfs ,都需要把n个字符串遍历一遍。然后对于每个字符串,都需要利用substr
进行字符串的比对,当符合题目要求时,就把字符串拼接,然后再dfs(注意这里是每一次的拼接都要进行dfs!!! 因为可以选择任意长度!!!)
另外,在每次dfs时,要更新最大值 maxlen = max(len, maxlen)
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 25;
int n;
string s[N];
int st[N];
string c;
int maxlen;
void dfs(string x, int y) //x 是拼接后的总的字符串,y是要截取的字符串
{
st[y]++;
string t = "";
int len = x.length();
maxlen = max(len, maxlen);
for (int i = 1; i <= n; i++)
{
for (int j =len- 1, k = 1; j > 0 && k < s[i].length(); j--, k++) //, && 不一样
{
if (st[i] < 2 && x.substr(j) == s[i].substr(0, k))
{
t = x.substr(0, j) + s[i];
dfs(t, i);
}
}
}
st[y]--;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> s[i];
}
cin >> c;
c = " " + c;
dfs(c, n + 1);
cout << maxlen - 1<< endl;
return 0;
}
/*
ABABABAB
ABABABC
ABABABAB
ABABABAB
ABABABC
*/
总结反思
-
输入数据的小技巧
-
substr的用法
- substr(a,b) 表示从字符串下标a开始截取b个
- substr(a) 表示从字符串下标a开始全部截取
-
在for循环中
for (int j =len- 1, k = 1; j > 0 && k < s[i].length(); j--, k++)
和
for (int j =len- 1, k = 1; j > 0 , k < s[i].length(); j--, k++)
不一样!!!
因为:在这个循环中,
j > 0 , k < s[i].length()
是循环继续执行的条件。这里使用了逗号操作符,
,这意味着j > 0
这个表达式会被执行,但它的结果不会用来决定循环是否继续。循环继续执行的唯一条件是k < s[i].length()
。逗号操作符允许在一个表达式的位置执行多个表达式,但只有最后一个表达式的结果会被用于逻辑判断。 -
在dfs中,不一定要明显的写出来当什么什么时候return,因为程序执行完会自动的return