题目描述:
题目解读:
给定由0,1组成的长度为n的字符串,执行翻转操作,即0变1,1变0;
判断执行一次翻转之后是否为回文。
解题思路:
寻找规律:如果翻转前已经是回文,或者左右对称位置数值不同,那么必然可以通过一次翻转得到回文。
遍历字符串,如果有对称位置数值不同,且不相邻,就输出NO;其余情况输出YES。
遇到数值不同的,先数量+1,然后记录了位置。
最后判断不同的数量是否大于1,然后判断如果位置不相邻,就输出NO。
判断是否相邻这里应该可以简化。
设置flag,初始值为0,第一次遇到不同的,flag变1;
然后向后遍历,如果遇到相同,且flag为1,则flag变2,表示已经有不同且不同之后又出现相同,此时如果后续遇到不同,则必输出NO了;
后续如果遇到不同,且flag=2,则flag变3,表示要输出NO
最后状态下:
flag=0,表示对称位置全相同;
flag=1,表示只有连续对称位置不同;
flag=2,表示只有一个位置不同,其他都相同;
flag=3,表示不连续位置不同。
代码实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#define MAX 50000 //注意题目中要求的变量取值范围
#include <iostream>
using namespace std;void Solve() {int n; string s;int i = 0;int flag = 0;int flag2 = 0;int alength = 0;int a[MAX];scanf("%d", &n);cin >> s;for (i = 0; i < n/2; i++) {if (s[i]!=s[n-i-1]) {flag++;a[alength++]=i;}}if (flag > 1) {for (i = 0; i < alength -1;i++) {if (a[i + 1] - a[i] > 1) {flag2 = 1;break;}}}if (flag2 == 1) printf("NO\n");else printf("YES\n");return;
}int main() {int t;scanf("%d", &t);while (t--) Solve();return 0;
}
优化:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <iostream>
using namespace std;void Solve() {int n;string s;int i = 0;int flag = 0;scanf("%d", &n);cin >> s;for (i = 0; i < n / 2; i++) {if (s[i] != s[n - i - 1]) {if (flag == 0) flag = 1;else if (flag == 2) flag = 3;}else {if (flag == 1) flag = 2;}}if (flag == 3) printf("NO\n");else printf("YES\n");return;
}int main() {int t;scanf("%d", &t);while (t--) Solve();return 0;
}
遇到的错误:越写越复杂了,需要新思路来简化代码。