将前文整个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
404

被折叠的 条评论
为什么被折叠?



