题目大意:
You are given a string s of n lowercase letters.
You have to delete exactly two letters from s , determine whether the string can become a palindrome after the change.
Definition of palindrome: If a string s of n lowercase letters is a palindrome, then for each si(1≤i≤n) ,si=sn−i+1。
For example, “ababa” and “abba” are palindromes, but “abab” not.
输入描述:
The first line contains an integer t(1≤t≤103) — the number of test cases.
For each test case, the first line contains an integer n(3≤n≤2*10^3) representing the length of s, the second line contains a string of length n.
It is guaranteed that the sum of n for all test cases does not exceed 10^4 .
输出描述:
If it is possible to change the string into a palindrome after deleting two letters from s, please output “Yes”, otherwise output “No”.
思路:
我第一次尝试用传统的最长公共子序列做法(O(N2)的时间复杂度)但是不知道为什么超时了,其他题解也有N2做法。其他的做法有迭代加深搜索,限制修改次数上限是2(虽说题目是必须修改两个字母,但是若修改一个字母能改出回文,则修改两个可以也是回文)。然后就是暴力,区间【L,R】,每次比较头尾,若不同,则递归两种情况,删除头或者删除尾。若相同,则缩小区间为【L+1,R-1】;终止条件一是L>=R,二是修改次数超过2次。
反思:
第一次做法用最长公共子序列做,改了N遍,都是TLE。还是对区间搜索不是很熟悉。做过的题目有时也是一种负担。。所以说做题不能浮光掠影,要多想。
代码:
#include<cstdio>
const int MAXN=2e3+10;
char a[MAXN];;
bool dfs(int l,int r,int num){
if(l>=r)return 1;
if(a[l]==a[r])return dfs(l+1,r-1,num);
if(num>=2)return 0;
return dfs(l+1,r,num+1)||dfs(l,r-1,num+1);
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d%s",&n,a);
if(dfs(0,n-1,0))printf("Yes\n");
else printf("No\n");
}
}