1

我有一个关于矩阵的问题。我有一个计算跳棋动作的程序;我用 Java 解决了它,但它运行得不够快,所以我决定在 C 中尝试它。

问题是在 Java 中我可以将二维矩阵作为参数传递给函数,但在 C 中我不能这样做。编译器说我不能。我在这里和网上挖掘,看到了一些动态分配之类的东西,但我不太明白。

我的问题是:

  • 如何将二维矩阵传递给我的函数checagem(它是一个递归函数)以使其工作?
  • 这是否有效(main()代码),因为这里显示了一个 0 循环?我不知道是因为矩阵还是什么。

这是代码:

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

int checagem(int m[][100], int xo, int xd, int yd, int n) {
    int r = 0;
    if (0 <= xd && xd < n && 0 <= yd && yd < n) {
        if (yd == 0) {
            if (m[yd][xd] != 1) {
                r += 1;
            }
        } else if (m[yd][xd] == 0 || m[yd][xd] == 2) {
            r += checagem(m, xd, xd - 1, yd - 1, n);
            r += checagem(m, xd, xd + 1, yd - 1, n);
        } else if (m[yd][xd] == 1) {
            if (xo - xd > 0) {
                if (pulavel(xd - 1, yd - 1, m, n)==1) {
                    r += checagem(m, xd, xd - 1, yd - 1, n);
                }
            } else if (xo - xd < 0) {
                if (pulavel(xd + 1, yd - 1, m, n)==1) {
                    r += checagem(m, xd, xd + 1, yd - 1, n);
                }
            }
        }
    } else {
        r += 0;
    }
    return r;
}

int pulavel(int x, int y, int m[][100], int n) {
    int r = 1;
    if (x < 0 || x > n - 1 || m[y][x] == 1) {
       r=0 ;
    }
    return r;
}

int main(){
    //variaveis
    int n = 0, t = 1, x = -1, y = -1, teste = 1;
    int i,j;
    //logica
    scanf("%d %*c",&t);

    while (teste > 0) {
        scanf("%d %*c",&n);
        if (n > 1 || n <= 100) {
            int tabuleiro[n][n];
            for (i = 0; i < n; i++) {
                char l[n];
                scanf("%s %*c", &l);
                for (j = 0; j < n; j++){
                    switch(l[j]){
                    case ('.'): tabuleiro[i][j] = 0;break;
                    case ('b'): tabuleiro[i][j] = 1;break;
                    case ('w'): tabuleiro[i][j] = 2;
                                x = j;
                                y = i;break;
                    }
                }
            }
            int r = checagem(tabuleiro, x, x, y, n);
            printf("%d", r); 
        }
    }
}

输入就像来自的比赛:http ://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=3108

4

1 回答 1

1

您的问题是您在函数中声明int tabuleiro[n][n];main()但您的checagem()函数不希望通过 VLA。您需要在数组之前传递维度,因此将其修改为:

int checagem(int n, int m[n][n], int xo, int xd, int yd)
{
    ...
}

然后确保你没有溢出数组的边界(因为 C 不会阻止你,当然)。

当然,您需要对 进行并行更改pulavel(),并更改对这两个函数的调用。

这编译OK;我没有尝试运行它。不要取数组的地址;它会让你感到困惑,即使它不会让编译器感到困惑(它只是在抱怨 中的类型不匹配scanf("%s %*c", &l);)。请升级您的代码以检查scanf()调用是否成功。我不确定您正在阅读什么格式scanf("%s %*c", l),但我怀疑它会对您不期望的数据造成损害。我重新排序了函数并制作了它们static(并添加voidint main(void))以避免来自我的标准 GCC 编译选项的编译警告:

gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -c ck.c

代码:

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

static
int pulavel(int n, int x, int y, int m[n][n])
{
    int r = 1;
    if (x < 0 || x > n - 1 || m[y][x] == 1)
       r=0;
    return r;
}

static
int checagem(int n, int m[n][n], int xo, int xd, int yd)
{
    int r = 0;
    if (0 <= xd && xd < n && 0 <= yd && yd < n) {
        if (yd == 0) {
            if (m[yd][xd] != 1) {
                r += 1;
            }
        } else if (m[yd][xd] == 0 || m[yd][xd] == 2) {
            r += checagem(n, m, xd, xd - 1, yd - 1);
            r += checagem(n, m, xd, xd + 1, yd - 1);
        } else if (m[yd][xd] == 1) {
            if (xo - xd > 0) {
                if (pulavel(n, xd - 1, yd - 1, m)==1) {
                    r += checagem(n, m, xd, xd - 1, yd - 1);
                }
            } else if (xo - xd < 0) {
                if (pulavel(n, xd + 1, yd - 1, m)==1) {
                    r += checagem(n, m, xd, xd + 1, yd - 1);
                }
            }
        }
    } else {
        r += 0;
    }
    return r;
}

int main(void)
{
    //variaveis
    int n = 0, t = 1, x = -1, y = -1, teste = 1;
    int i,j;
    //logica
    scanf("%d %*c",&t);

    while (teste > 0) {
        scanf("%d %*c",&n);
        if (n > 1 || n <= 100) {
            int tabuleiro[n][n];
            for (i = 0; i < n; i++) {
                char l[n];
                scanf("%s %*c", l);
                for (j = 0; j < n; j++){
                    switch(l[j]){
                    case ('.'): tabuleiro[i][j] = 0;break;
                    case ('b'): tabuleiro[i][j] = 1;break;
                    case ('w'): tabuleiro[i][j] = 2;
                                x = j;
                                y = i;break;
                    }
                }
            }
            int r = checagem(n, tabuleiro, x, x, y);
            printf("%d", r); 
        }
    }
}
于 2013-04-19T00:49:48.180 回答