#include <stdio.h>
#include <stdbool.h>

#define NUM_PLACES 4
 
void printPath(int *path) {
    for (int i = 0; i < NUM_PLACES; ++i)  
        printf("%c", 'A' + path[i]); // 将数字转换为对应的字母（例如：0 -> 'A', 1 -> 'B' 等）
    printf("\n");  
}

// 回溯函数：尝试构建所有可能的路径组合
void backtrack(int *path, bool used[NUM_PLACES], int step) {
    // 如果已经到达了最后一个步骤，则打印路径
    if (step == NUM_PLACES) {
        printPath(path); // 调用打印函数
        return;
    } 
    // 尝试每一个可能的下一个位置
    for (int next = 0; next < NUM_PLACES; ++next) {
        // 如果这个位置还没有被使用过
        if (!used[next]) {
            // 特殊情况处理：如果当前要放置的是 A (即 next == 0)
            // 并且后面还有空间放置 B (即 step + 1 < NUM_PLACES)
            // 同时 B 还没有被使用过 (!used[1])
            if (next == 0 && step + 1 < NUM_PLACES && !used[1]) {
                // 把 A 和 B 作为一对连续的位置放置
                path[step] = 0; // 放置 A
                path[step + 1] = 1; // 放置 B
                used[0] = used[1] = true; // 标记 A 和 B 已经被使用

                // 继续递归寻找后续的路径
                backtrack(path, used, step + 2);

                // 回溯：取消标记 A 和 B 的使用状态
                used[0] = used[1] = false;
            } else if (next != 0 && next != 1) { // 如果不是 A 或 B
                // 只放置 C 或者 D，确保 A 总是紧跟着 B 出现
                path[step] = next; // 放置 C 或 D
                used[next] = true; // 标记当前位置已被使用

                // 继续递归寻找后续的路径
                backtrack(path, used, step + 1);

                // 回溯：取消标记当前位置的使用状态
                used[next] = false;
            }
        }
    }
}

int main() {
    int path[NUM_PLACES]; // 创建一个用来存储路径的数组
    bool used[NUM_PLACES] = {false}; // 创建一个布尔数组来追踪哪些位置已经被使用

    // 开始回溯，从一个空路径开始
    backtrack(path, used, 0);

    return 0;
}