结构数组有问题解决C中的问题

Having problem with array of struct solving a problem in C

我正在想办法解决这个问题:

We have n ≥ 1 parallelepiped-shaped boxes, labeled as 0, 1,… n - 1; box i has width x [i], height y [i] and depth z [i] (strictly positive real values).
We want to insert as many boxes one inside the other, similar to a "matryoshka": box i can be contained in box j if the dimensions of box i are strictly smaller than the corresponding ones of box j, that is, if x [i] <x [j] and y [i] <y [j] and z [i] <z [j].
Implement an efficient algorithm to determine the maximum number of boxes that can be inserted into each other respecting the previous constraints. The boxes cannot be rotated. The program accepts a single parameter on the command line that represents the name of the input file, the content of which has the following structure:
n
x [0] y [0] z [0]
...
x [n-1] y [n-1] z [n-1]
The output must list the boxes that are part of the optimal solution, one box per line, starting with the outermost one; for each of them the dimensions must be reported (as per input file).

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef struct box {
    float x, y, z;    //width x, height y, depth z
}Box;

int cmpfunc (const void *a, const void *b) {
    Box *boxA = (Box *)a;
    Box *boxB = (Box *)b;
    return (boxA->x - boxB->x);
}

void maxBoxes (Box *box, int n) {
    qsort (box, n, sizeof(Box), cmpfunc);

    Box *max_boxes;

    max_boxes = (Box*)malloc(n * sizeof(Box));
    assert (max_boxes != NULL);

    int n_boxes = 0;

    for (int i=0; i<n; i++) {
        for (int j=0; j < i; j++) {
            if (box[i].x < box[j].x && box[i].y < box[j].y && box[i].z < box[j].z) {
                    max_boxes[i] = box[i];
                    n_boxes++;
            }
        }
    }

    printf ("%d boxes\n", n_boxes);
    
    for (int i=0; i<n_boxes; i++) {
        printf("Box %d: %.2f %.2f %.2f\n", i, max_boxes[i].x, max_boxes[i].y, max_boxes[i].z);
    }
}

int main (int argc, char *argv[]) {
    FILE *filein = stdin;
    Box *box;
    int n = 0;

    if (argc > 1) {
        filein = fopen(argv[1], "r");
        if (filein == NULL) {
            fprintf (stderr, "Can not open %s\n", argv[1]);
            return EXIT_FAILURE;
        }
    }

    fscanf (filein, "%d", &n);
    if (n<=0) {
        fprintf (stderr, "ERROR: arguments number equal to 0\n");
        exit (EXIT_FAILURE);
    }
    
    box = (Box*)malloc(n * sizeof(Box));
    assert (box != NULL);

    for (int i=0; i<n; i++) {
        fscanf (filein, "%f %f %f", &box[i].x, &box[i].y, &box[i].z);
    }

    maxBoxes (box, n);
    fclose(filein);
}

我试过了,但我的代码 returns 屏幕上只有“0 个框”。 我想我的结构有一些问题。我想创建一个结构数组,但我不知道我做对了没有。

如果你有什么建议,我很乐意听取。

您可以通过根据“包含”关系对盒子进行拓扑排序来解决问题,并使用动态规划来跟踪可以将多长的盒子链放入先前的盒子中。 从不包含其他框的框开始。 当您添加一个新框时,只需遍历适合给定框的框,以找到具有适合当前框的最长链的框。

最后,从分数最大的盒子开始重构链。 复杂度为 O(N^2)。 这是代码:

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

int main() {
    int n;
    scanf("%d", &n);
    struct box {
        float x,y,z;
        // the longest chain, 0 - score is undefined
        int score;
        // number of non-processes boxes that fits to this box
        int deg;
        int prev;
    };
    // allocate and load
    struct box *B = calloc(n, sizeof *B);
    for (int i = 0; i < n; ++i) {
        scanf("%f %f %f", &B[i].x, &B[i].y, &B[i].z);
        B[i].prev = -1;
    }

    #define CONTAINS(a,b) (a.x > b.x && a.y > b.y && a.z > b.z)

    // compute number of boxes that fit to n-th box
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            if (CONTAINS(B[i], B[j]))
                B[i].deg++;
    
    for (;;) {
        int i;
        // find not processed box that 
        for (i = 0; i < n; ++i) {
            if (B[i].deg == 0 && B[i].score == 0)
                break;
        }

        // no boxes were found, quit
        if (i == n) break;

        // mark as processed, set score to 1, as box contains itself 
        B[i].score = 1;

        // look for the box with the longest chain that fits to box `i`
        for (int j = 0; j < n; ++j) {
            if (CONTAINS(B[i], B[j]) && B[j].score + 1 > B[i].score) {
                B[i].score = B[j].score + 1;
                B[i].prev = j;
            }
        }

        // reduce deg (number of unprocessed boxes that fits given box)
        // for boxes that contains i-th box
        for (int j = 0; j < n; ++j) {
            if (CONTAINS(B[j], B[i]))
                B[j].deg--;
        }
    }

    // find the box with the best score
    int best = 0;
    for (int i = 0; i < n; ++i)
        if (B[i].score > B[best].score)
            best = i;

    printf("%d boxes\n", B[best].score);
    for (int i = best; i != -1; i = B[i].prev)
        printf("box %d: %g %g %g\n", i, B[i].x, B[i].y, B[i].z);

    free(B);
}

输入:

10
10 3 4
2 2 3
3 2.5 3
4.4 5 6
7 5.1 7.4
9 8.7 5.6
8.7 6.5 9.5
2.5 6.5 7.3
5.7 8.7 9.3
7.6 5.1 6.2

产生了预期的输出:

4 boxes
box 6: 8.7 6.5 9.5
box 4: 7 5.1 7.4
box 3: 4.4 5 6
box 1: 2 2 3