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

#define NUM_PLACES 4

// 函数：打印路径，将索引转换为1到4的数字表示
void printPath(int *path) {
    for (int i = 0; i < NUM_PLACES; ++i) {
        printf("%d ", path[i] + 1); // 将索引转换为1-based索引（即0变为1, 1变为2等）
    }
    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]) { // 如果该地点还没有被访问过
            if (next == 0 && step + 1 < NUM_PLACES && !used[1]) {
                // 如果当前要放置的是地点1，并且后面还有空间且地点2未被使用，
                // 则将地点1和地点2作为一个单元放置在一起
                path[step] = 0;          // 放置地点1
                path[step + 1] = 1;      // 紧接着放置地点2
                used[0] = used[1] = true; // 标记地点1和地点2为已使用
                backtrack(path, used, step + 2); // 递归尝试下一步
                used[0] = used[1] = false; // 回溯，恢复状态
            } else if (next != 0 && next != 1) {
                // 如果当前不是选择地点1或地点2，则可以选择地点3或地点4
                path[step] = next; // 放置地点3或地点4
                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;
}