思路是贪心法,每次从右往左找和第一个元素相等的元素,计算移动次数,找不到那就是中间位置或者Impossible,交换后进入下一次贪心。本实现的特点是,不移动元素,而是将元素在下一次贪心时“不再考虑”。
希望大家帮忙找找bug(
#include<stdio.h>
char string[80];
int main() {
int length, loop_count = 1;
scanf("%d%s", &length, string);
int half = length / 2, need_mid = length - 2 * half, jump_hole, answer = 0;//need_mid非零,意味着现在还需要一个位于中间的数
int head = -1, tail;//本来该写0,写-1是为了方便
char string_head;
label_1://为了方便跳出内层循环,不得不使用goto(别打我
while (loop_count++ < half) {//无论length是奇数是偶数,一定会循环half-1次。loop_count仅仅用来控制循环次数
jump_hole = 0;
tail = length;//本来该写length-1,写length是为了方便
do string_head = string[++head];
while (string_head == 0);//head对应的值可能已经不在考虑范围内
while (--tail > head) {//从最后向前寻找相同的值
if (string[tail] == 0) jump_hole++;//为了计数时,不要算上不在考虑范围内的部分
else if (string_head == string[tail]) {
string[tail] = 0;//之后不再考虑这一项
answer += length - 1 - tail - jump_hole;
//printf("%c 向右移动 %d\n",string_head, length - 1 - tail - jump_hole);
goto label_1;
}
}
if (need_mid) {
need_mid = 0;
answer += (half > head)?half-head:head-half;
} else {
printf("Impossible");
return 0;
}
}
printf("%d", answer);
return 0;
}