#P1477. 第1题-小红的回文修改
-
1000ms
Tried: 280
Accepted: 42
Difficulty: 4
所属公司 :
拼多多
时间 :2023年8月22日
-
算法标签>思维
第1题-小红的回文修改
思路:思维
首先考虑将 s[i] 与 s[j] 修改为相同,满足 0≤i,j≤n−1,i+j=n−1。
如果修改了 cnt 次:
-
cnt>k ,则必然无法修改为回文串。
-
cnt==k ,则恰好可以修改为回文串
-
cnt<k 但是 n 是奇数,那么多的 k−cnt 次都用来修改最中间的字符即可
-
cnt<k 但是 n 是偶数,那么多的 k−cnt 可以这么考虑:
如果 k−cnt 为偶数,那么我们对于相同的两个字符 s[i]=s[j],修改 2k−cnt 次这两个字符即可。
如果 k−cnt 为奇数,且 cnt>0,那么我们对于修改前不相同的两个字符 s[i] 和 s[j] ,假设 s[i]=′a′,s[j]=′b′ ,那么我们不把 s[i] 修改为和 s[j] 一样,此时剩余了 k−cnt+1 次,因为 k−cnt 是奇数,所以 k−cnt+1 是偶数且大于等于 2 。这时候可以将 s[i] 和 s[j] 都修改为 ′c′ 。后面剩余的 k−cnt−1 次,均可以选择 s[i] 和 s[j] 同时修改为一个同样的字符即可。
如果 k−cnt 为奇数,且 cnt=0 ,如果 k−cnt>1 ,则必然可以修改为回文串,否则 k−cnt=1 ,就无法修改为回文串。
时间复杂度:O(n)
代码
C++
#include <bits/stdc++.h>
using namespace std;
string s;
int k;
void solve() {
cin >> s;
cin >> k;
int n = int(s.size());
// 先查看有多少需要修改的
int cnt = 0;
for (int l = 0, r = n - 1; l < r; ++l, --r) {
if (s[l] != s[r]) {
cnt += 1;
}
}
if (cnt > k) {
cout << "No\n";
return;
}
if (cnt == k || (n & 1)) {
cout << "Yes\n";
return;
}
// k > cnt, n 是偶数
// 如果 k - cnt 是偶数,则修改完后,将一个字符反复修改再修改回来即可
if ((k - cnt) % 2 == 0) {
cout << "Yes\n";
} else {
// 如果 k - cnt 是奇数,cnt > 0 或者 (cnt == 0 && k - cnt > 1),则可以
if (cnt > 0 || k - cnt > 1) {
cout << "Yes\n";
} else {
// cnt == 0 and k - cnt == 1 ,则不可以
cout << "No\n";
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) solve();
return 0;
}
Java
import java.util.Scanner;
public class Main {
private static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
int T = scanner.nextInt();
while (T-- > 0) {
solve();
}
}
private static void solve() {
String s = scanner.next();
int k = scanner.nextInt();
int n = s.length();
int cnt = 0;
for (int l = 0, r = n - 1; l < r; ++l, --r) {
if (s.charAt(l) != s.charAt(r)) {
cnt += 1;
}
}
if (cnt > k) {
System.out.println("No");
return;
}
if (cnt == k || (n & 1) == 1) {
System.out.println("Yes");
return;
}
if ((k - cnt) % 2 == 0) {
System.out.println("Yes");
} else {
if (cnt > 0 || k - cnt > 1) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}
}
}
题目内容
小红有一个字符串 s 。
现在小红给这个串恰好 k 次修改,问修改后的串是否可能是回文串?需要保证修改一个字符后,修改前后的字符不同。
输入描述
第一行,一个整数 T(1≤T≤10) ,表示 T 组数据。
接下来对于每组数据,
第一行,输入一个字符串 s(1≤len(s)≤106) 。
第二行,输入一个整数 k(1≤k≤106) ,表示修改次数。
输出描述
输出 Yes 表示修改后可以为回文串,输出 No 表示在 k 次修改后不可能为回文串。
样例
输入
4
aaa
1
bac
2
bbcc
3
cdefgh
2
输出
Yes
Yes
Yes
No