题目描述:
题目解读:
给定由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;
}
遇到的错误:越写越复杂了,需要新思路来简化代码。