利用DeepSeek改写pythonq集合求解算法为C语言

前文整个python改写成c语言,用二维数组代替所有列表,数组元素用_int128,以处理大于8x8的格点

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

// 使用int128处理大数,如果编译器不支持可以改用多个uint64_t
typedef __int128  int128_t;

typedef struct {
    int x;
    int y;
    int128_t bit;
    int rn;
} Point;

typedef struct {
    int128_t bit;
    int x;
    int y;
    int128_t bit2;
    int rn;
} Compatible;

// 比较函数用于排序
int compare_rn(const void *a, const void *b) {
    const Compatible *ca = (const Compatible *)a;
    const Compatible *cb = (const Compatible *)b;
    return ca->rn - cb->rn;
}

void print_int128(int128_t n) {
    if (n == 0) {
        printf("0");
        return;
    }
    
    char buffer[50];
    int i = 0;
    int128_t num = n;
    
    if (num < 0) {
        printf("-");
        num = -num;
    }
    
    while (num > 0) {
        buffer[i++] = '0' + (num % 10);
        num /= 10;
    }
    
    for (int j = i - 1; j >= 0; j--) {
        printf("%c", buffer[j]);
    }
}

int main() {
    int n_size = 9; // I = {1,2,3,4,5}
    int total_points = n_size * n_size;
    
    // 创建A数组
    Point *A = (Point *)malloc(total_points * sizeof(Point));
    int idx = 0;
    for (int y = 1; y <= n_size; y++) {
        for (int x = 1; x <= n_size; x++) {
            int rn = (y - 1) * n_size + (x - 1);
            int128_t bit_value = ((int128_t)1) << rn;
            A[idx].x = x;
            A[idx].y = y;
            A[idx].bit = bit_value;
            A[idx].rn = rn;
            idx++;
        }
    }
    
    // 创建C数组
    Compatible *C = (Compatible *)malloc(total_points * sizeof(Compatible));
    for (int i = 0; i < total_points; i++) {
        int128_t bit2_sum = 0;
        for (int j = 0; j < total_points; j++) {
            if ((A[i].x - A[j].x) * (A[i].y - A[j].y) <= 0) {
                bit2_sum += A[j].bit;
            }
        }
        C[i].bit = A[i].bit;
        C[i].x = A[i].x;
        C[i].y = A[i].y;
        C[i].bit2 = bit2_sum;
        C[i].rn = A[i].rn;
    }
    
    // 按rn排序C
    qsort(C, total_points, sizeof(Compatible), compare_rn);
    
    // 初始化b数组 [cnt, bit, bit2, rn]
    int128_t **b = (int128_t **)malloc(total_points * sizeof(int128_t *));
    int b_size = 0;
    for (int i = 0; i < total_points; i++) {
        b[b_size] = (int128_t *)malloc(4 * sizeof(int128_t));
        b[b_size][0] = 1; // cnt
        b[b_size][1] = C[i].bit; // bit
        b[b_size][2] = C[i].bit2; // bit2
        b[b_size][3] = C[i].rn; // rn
        b_size++;
    }
    
    // 递归部分
    int changed = 1;
    while (changed) {
        changed = 0;
        
        // 创建新数组
        //int128_t **new_b = (int128_t **)malloc(total_points * total_points * sizeof(int128_t *));
        int128_t **new_b = (int128_t **)malloc(b_size*total_points * sizeof(int128_t *));
        int new_b_size = 0;
        
        for (int i = 0; i < b_size; i++) {
            int start_rn = b[i][3] + 1;
            for (int j = start_rn; j < total_points; j++) {
                if ((b[i][2] & C[j].bit) > 0) {
                    new_b[new_b_size] = (int128_t *)malloc(4 * sizeof(int128_t));
                    new_b[new_b_size][0] = b[i][0] + 1; // cnt
                    new_b[new_b_size][1] = b[i][1] + C[j].bit; // bit
                    new_b[new_b_size][2] = b[i][2] & C[j].bit2; // bit2
                    new_b[new_b_size][3] = C[j].rn; // rn
                    new_b_size++;
                }
            }
        }
        

        fprintf(stderr, ". %d", new_b_size);
        if (new_b_size > 0) {
        // 释放旧的b数组
        for (int i = 0; i < b_size; i++) {
            free(b[i]);
        }
        free(b);
            b = new_b;
            b_size = new_b_size;
            changed = 1;
        } else {
            free(new_b);
        }
    }
       
    // 找到最大cnt
    int max_cnt = 0;
    for (int i = 0; i < b_size; i++) {
        if (b[i][0] > max_cnt) {
            max_cnt = b[i][0];
        }
    }

    // 输出结果
    printf("最大集合大小: %d\n", max_cnt);
    printf("找到的最大集合个数:%d\n", b_size);
    /*
    for (int i = 0; i < b_size; i++) {
        if (b[i][0] == max_cnt) {
            printf("集合 %d: ", i + 1);
            for (int j = 0; j < total_points; j++) {
                if (b[i][1] & A[j].bit) {
                    printf("(%d,%d)", A[j].x, A[j].y);
                }
            }
            printf("\n");
        }
    }
    */
    // 清理内存
    for (int i = 0; i < b_size; i++) {
        free(b[i]);
    }
    free(b);
    free(A);
    free(C);
    
    return 0;
}

原作有一处错误,导致n_size=3时可以输出结果,n_size=4报错corrupted size vs. prev_size,原因是分配数组指针的大小total_points * total_points 过小,从两重循环的数量看,应该是b_size*total_points,修改之后,n直到8都能正常输出,而在n=9时,分配内存出错,可见穷举法对于此类数学问题不适合。

gcc sql2c2.c -o sql2c2 -O3
time ./sql2c2
最大集合大小: 11
找到的最大集合个数:252

real    0m0.009s
user    0m0.005s
sys     0m0.000s

最大集合大小: 13
找到的最大集合个数:924

real    0m0.060s
user    0m0.025s
sys     0m0.038s

最大集合大小: 15
找到的最大集合个数:3432

real    0m0.654s
user    0m0.353s
sys     0m0.303s

查看分配的二维数组b大小

time ./sql2c2
. 1232. 11872. 69524. 272944. 759752. 1549936. 2360501. 2703512. 2322180. 1475208. 673134. 208824. 39468. 3432. 0最大集合大小: 15
找到的最大集合个数:3432

real    0m0.614s
user    0m0.304s
sys     0m0.316s

gcc sql2c2.c -o sql2c2 -O3
time ./sql2c2
. 1944. 23256. 169344. 831600. 2924208. 7642512. 15195843. 23301307Segmentation fault (core dumped)

real    0m37.285s
user    0m1.700s
sys     0m7.445s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值