牛客练习赛42 A.字符串(思维)
题目描述
给定两个等长的由小写字母构成的串A,B,其中∣A∣=∣B∣=n|A|=|B|=n∣A∣=∣B∣=n
现在你需要求出一个子区间[l,r][l,r][l,r]使得
LCP(A[l,r],B[l,r])LCP(A[l,r],B[l,r])LCP(A[l,r],B[l,r]) ×\times× LCS(A[r,l],B[r,l])LCS(A[r,l],B[r,l])LCS(A[r,l],B[r,l]) +LCP(A[l,r],B[l,r])LCP(A[l,r],B[l,r])LCP(A[l,r],B[l,r]) +LCS(A[r,l],B[rl])LCS(A[r,l],B[rl])LCS(A[r,l],B[rl])最大,并输出这个值。
其中,LCP(S,T)LCP(S,T)LCP(S,T)表示S和T的最长公共前缀,LCS(S,T)LCS(S,T)LCS(S,T)表示S和T的最长公共后缀。
输入描述
第一行一个字符串。
第二行一个字符串。
输出描述
一行一个整数,表示答案。
示例1
输入 |
---|
aaabbbcccddd |
aaaddddddddd |
输出 |
15 |
说明 |
选择l=1,r=12l=1,r=12l=1,r=12是一种可行的最优解。 |
备注:
对于所有数据,保证nnn ≤\leq≤ 200000,串A,BA,BA,B仅由小写字母构成。
题目大意
这道题题目的描述很直接,没有弯弯绕绕,已经告诉你需要求的东西。
解题思路
题目已知告诉你需要求的东西(最长公共前缀和最长公共后缀)。明显要使式子LCP(A[l,r],B[l,r])LCP(A[l,r],B[l,r])LCP(A[l,r],B[l,r]) ×\times× LCS(A[r,l],B[r,l])LCS(A[r,l],B[r,l])LCS(A[r,l],B[r,l]) +LCP(A[l,r],B[l,r])LCP(A[l,r],B[l,r])LCP(A[l,r],B[l,r]) +LCS(A[r,l],B[rl])LCS(A[r,l],B[rl])LCS(A[r,l],B[rl])最大,问题就转变为求LCP(S,T)LCP(S,T)LCP(S,T),LCS(S,T)LCS(S,T)LCS(S,T)的最大值。其实就是求字符串AAA和BBB子串相等的最长长度
AC代码
#include<bits/stdc++.h> const int Max_N=2e5+6; typedef long long ll; typedef unsigned long long ull; using namespace std; int main(int argc, char const *argv[]) { string a,b; cin>>a>>b; ll ans=0,len=a.size(); ll res=0,mid=0; for(int i=0;i<len;i++) { if(a[i]==b[i]) ans++; else { res=max(res,ans); ans=0; } } res=max(res,ans); res=res*res+2*res; cout<<res<<endl; return 0; }
总结
思路在自己仔细读第二遍题目的时候就大概有了。想说一下自己为什么wa了两发,第一次犯了两个低级的错误,else语句中在更新了res之后并没有使ans赋值为0,同时在for循环完了之后没有对res进行更新。第二次wa是指改正了其中一个bug,没有改正的完全。
- 牛客练习赛42 B. SHTMYCBDFTT解题报告(思维)
- 牛客练习赛10 B栈和排序【思维】
- 牛客练习赛13 D 题 幸运数字IV 【康拓逆展开 + 思维】
- 牛客练习赛13_C-幸运数字Ⅲ(思维)
- 牛客练习赛13 A B C F【二分+思维】
- 牛客练习赛7 E 题 珂朵莉的数列 【树状数组 + 思维】
- 牛客练习赛11-B-假的字符串(字典树+拓扑)
- 牛客练习赛11 B、假的字符串
- 牛客练习赛13-D:幸运数字Ⅳ(思维)
- 牛客练习赛11 B-假的字符串(字典树+拓扑排序找环)
- 【牛客练习赛13】 A B C D【康拓展开】 E【DP or 记忆化搜索】 F 【思维】
- 牛客练习赛23-A/B/C/D/F
- (42) 排序二叉树 / 计算机程序的思维逻辑
- 牛客练习赛8 F题 莫队算法
- 面试题42:翻转单词顺序VS左旋转字符串
- 牛客练习赛25 C 再编号
- 牛客练习赛9
- 牛客练习赛9
- 牛客练习赛9 B - 珂朵莉的值域连续段
- 动态规划: 套路之推导公式 黑暗字符串 牛客