// 演算法 / Algorithm: 對每個對稱配對 (a, b)，目標和 x 所需的修改次數對 x 是一個
// "梯形" 函數 (2 → 1 → 0 → 1 → 2)。用差分陣列累計所有配對的代價，做一次前綴和
// 即可在 O(n + limit) 內找出最小的 f(x)。
// For each pair, the cost-vs-x curve is a fixed shape; sum them with a diff array
// and prefix-scan to find min f(x) in O(n + limit).

#include <stdlib.h>  // 引入 calloc / free / for calloc and free

int minMoves(int* nums, int numsSize, int limit) {
    int n = numsSize;                              // n 是陣列長度 / array length
    int size = 2 * limit + 2;                       // d 的大小需涵蓋索引 2..2*limit+1 / size covers indices up to 2*limit+1
    int* d = (int*)calloc(size, sizeof(int));       // calloc 配置並清零記憶體 / calloc allocates zero-filled memory
    if (d == NULL) return 0;                        // 防禦性檢查 / defensive null check

    for (int i = 0; i < n / 2; i++) {               // 走訪每組對稱配對 / iterate over each symmetric pair
        int a = nums[i];                            // 左邊元素 / left element of the pair
        int b = nums[n - 1 - i];                    // 右邊元素 (鏡像位置) / right element (mirror index)
        int lo = a < b ? a : b;                     // 較小值 / smaller value
        int hi = a < b ? b : a;                     // 較大值 / larger value

        // 從 x = lo+1 開始，本配對的代價從 2 掉到 1 / at x = lo+1 the cost drops 2 → 1
        d[lo + 1] -= 1;
        // 從 x = hi+limit+1 開始，本配對的代價又彈回 2 / at x = hi+limit+1 the cost climbs back 1 → 2
        d[hi + limit + 1] += 1;
        // x = lo+hi 時剛好原本就湊到 x，代價再扣 1 變 0 / at x = lo+hi the cost drops 1 → 0
        d[lo + hi] -= 1;
        // x = lo+hi+1 時離開那個點，代價彈回 1 / at x = lo+hi+1 the cost climbs back 0 → 1
        d[lo + hi + 1] += 1;
    }

    int ans = n;        // 最壞情況：每對都需 2 次修改，共 n 次 / worst case: every pair costs 2, total = n
    int cur = n;        // cur 累積 f(x)；起點取 n 代表 "所有配對皆代價 2" 的基線 / running f(x), baseline = n
    for (int x = 2; x <= 2 * limit; x++) {          // 掃過所有合法目標 x / sweep all valid target sums
        cur += d[x];                                 // 套用差分增量 = 前綴和 / apply diff = take prefix sum
        if (cur < ans) ans = cur;                    // 更新最小值 / track minimum
    }

    free(d);            // 釋放動態記憶體，避免洩漏 / free heap memory to avoid leaks
    return ans;         // 回傳最少修改次數 / return minimum number of moves
}
