秋招模拟赛第41场|2023.08.27-字节跳动秋招第二场
- Status
- Done
- Rule
- IOI
- Problem
- 4
- Start at
- 2023-9-8 19:00
- End at
- 2023-9-8 21:00
- Duration
- 2 hour(s)
- Host
- Partic.
- 38
You cannot submit for this problem because the contest is ended. You can click "Open in Problem Set" to view this problem in normal mode.
由于题目说只能改一次,所以我们可以很暴力的去解决这个问题:枚举改的这一次到底使用在哪?
我们要使用修改机会,只会在这两种情况下:
1.修改使得LCS更大
2.修改使得LCP更大
所以模拟这两种情况:
1.从左往右遇到第一个s,t 不相等的位置,修改使其相等,求一下相似度。
2.从右往左遇到第一个s,t不相等的位置,修改使其相等,求一下相似度。
两者最大值即为答案。
#include <bits/stdc++.h>
using namespace std;
int getLcp (string a , string b){
int n = a.size();
int m = b.size();
for (int i = 0 ; i < min(n , m) ; i++){
if (a[i] != b[i]) return i;
}
return min(n , m);
}
int getLcs (string a , string b){
string ra = a;
string rb = b;
reverse(ra.begin() , ra.end());
reverse(rb.begin() , rb.end());
return getLcp(ra , rb);
}
long long solve(string a , string b){
int n = a.size();
int m = b.size();
char t;
long long res1 = 1LL * getLcp(a , b) * getLcs(a , b); // 初始为最大可能取值
long long res2 = res1;
for (int i = 0 ; i < min(n , m) ; i++){ // 模拟情况1
if (a[i] != b[i]) {
t = a[i];
a[i] = b[i];
res1 = 1LL * getLcp(a , b) * getLcs(a , b);
a[i] = t;
break;
}
}
for (int i = 0 ; i < min(n , m) ; i++){ // 模拟情况2
if (a[n - i - 1] != b[m - i - 1]) {
t = a[n - i - 1];
a[n - i - 1] = b[m - i - 1];
res2 = 1LL * getLcp(a , b) * getLcs(a , b);
a[n - i - 1] = t;
break;
}
}
return max(res1 , res2); // 返回
}
int main() {
string a , b;
cin >> a >> b;
cout << solve(a , b) << endl;
return 0;
}
def get_lcp(a, b):
n = len(a)
m = len(b)
for i in range(min(n, m)):
if a[i] != b[i]:
return i
return min(n, m)
def get_lcs(a, b):
ra = a[::-1]
rb = b[::-1]
return get_lcp(ra, rb)
def solve(a, b):
n = len(a)
m = len(b)
res1 = get_lcp(a, b) * get_lcs(a, b) # Initial maximum possible value
res2 = res1
for i in range(min(n, m)): # Simulate case 1
if a[i] != b[i]:
t = list(a)
g = t[i]
t[i] = b[i]
a = "".join(t)
res1 = get_lcp(a, b) * get_lcs(a, b)
t[i] = g
a = "".join(t) # Restore a
break
for i in range(min(n, m)): # Simulate case 2
if a[n - i - 1] != b[m - i - 1]:
t = list(a)
g = a[i]
t[n - i - 1] = b[m - i - 1]
a = "".join(t)
res2 = get_lcp(a, b) * get_lcs(a, b)
t[i] = g
a = "".join(t) # Restore a
break
return max(res1, res2) # Return the maximum result
a = input()
b = input()
print(solve(a, b))
import java.util.Scanner;
public class Main {
public static int getLcp(String a, String b) {
int n = a.length();
int m = b.length();
for (int i = 0; i < Math.min(n, m); i++) {
if (a.charAt(i) != b.charAt(i)) {
return i;
}
}
return Math.min(n, m);
}
public static int getLcs(String a, String b) {
StringBuilder ra = new StringBuilder(a).reverse();
StringBuilder rb = new StringBuilder(b).reverse();
return getLcp(ra.toString(), rb.toString());
}
public static long solve(String a, String b) {
int n = a.length();
int m = b.length();
char[] arr = a.toCharArray();
long res1 = (long) getLcp(a, b) * getLcs(a, b); // Initial maximum possible value
long res2 = res1;
for (int i = 0; i < Math.min(n, m); i++) { // Simulate case 1
if (arr[i] != b.charAt(i)) {
char t = arr[i];
arr[i] = b.charAt(i);
a = new String(arr);
res1 = (long) getLcp(a, b) * getLcs(a, b);
arr[i] = t; // Restore a
break;
}
}
for (int i = 0; i < Math.min(n, m); i++) { // Simulate case 2
if (arr[n - i - 1] != b.charAt(m - i - 1)) {
char t = arr[n - i - 1];
arr[n - i - 1] = b.charAt(m - i - 1);
a = new String(arr);
res2 = (long) getLcp(a, b) * getLcs(a, b);
arr[n - i - 1] = t; // Restore a
break;
}
}
return Math.max(res1, res2); // Return the maximum result
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String a = scanner.next();
String b = scanner.next();
System.out.println(solve(a, b));
}
}
给定两个字符串s , t
lcp(s,t) : 最长相同前缀长度
lcs(s,t) : 最长相同后缀长度
f(s,t)=lcp(s,t)∗lcs(s,t) : 字符串相似度
现在小红可以进行最多一次修改: s的一个小写字母改成另一个小写字母,使得相似度f(s,t)尽量大,请输出这个相似度!
第一行输入一个仅包含小写字母的字符串s。
第二行输入一个仅包含小写字母的字符串t。
1≤len(s),len(t)≤1e5
输出一个整数。
输入
bad
baab
输出
4
说明
将s串的第三个字符改成'b',s串变成"bab"。最长相同前缀和后缀分别是"ba"和"ab"。