[PTA]完美的代价

思路是贪心法,每次从右往左找和第一个元素相等的元素,计算移动次数,找不到那就是中间位置或者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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值