edu163div2D

https://mirror.codeforces.com/contest/1948/problem/D

题目大意:求最长串联重复子串

串联重复(长度偶数)前后相等,如abab(ab = ab)

子串,连续的(不连续的叫子序列)

这场的D有点意思,一开始只写出了n3复杂度的,理所当然的被hack了 、、

n <= 5000

记一下n2的想法

3次做法如下,最容易想的暴力,枚举起点终点,判断这个范围行不行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
typedef long long ll;

int main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T;
cin>>T;
while(T--){
string s;
cin>>s;
int n = s.size();
int ans = 0;
for(int i = 0; i < n; i++){ //枚举起点
if(ans > n-i) break;
for(int j = i + 1; j < n; j++){ //枚举终点
if(j - i > n - j) break;
int l = i, r = j;
int sum = 0;
bool flag = 0;
while(l < j && r < n){ //判断这个范围
if(s[l] == s[r] || s[l] == '?' || s[r] == '?'){
sum+=2;
l++;
r++;
}
else{
flag = 1;
break;
}
}
if(!flag) ans = max(ans, sum);
}
}
cout<<ans<<endl;
}
return 0;
}

平方做法如下,主要利用了子串的连续性进行优化

其实就是直接跳到失匹位置

如acabazab,len为4时

acab azab相等cnt+1

acab azab不相等cnt = 0

类推,最长是2

1
2
3
4
5
6
7
8
for(int len = n/2; len; len--){//逆序枚举长度
cnt = 0;
for(int i = 0; i + len < n; i++){//枚举起点
if(s[i] == s[len+i] || s[i] == '?' || s[len+i] == '?') cnt++;
else cnt = 0;
if(cnt == len) return len * 2;
}
}
  • Copyrights © 2023-2024 Kano
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信