簡體   English   中英

為什么我的代碼在這個問題中不能正常工作

[英]Why my code didn't work correct in this problem

網格旅行問題

她基本上是遞歸問題,就是這樣: 網格旅行問題

這是我的解決方案:

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

int gridtravel(int r, int c) {
    if (r == 1 && c == 1) return 1;
    if (r == 0 || c == 0) return 0;
    return gridtravel(r - 1, c) + gridtravel(r, c - 1); 
}

int main() {
    int r, c;
    scanf("%i%i", &r, &c);
    printf("%i\n", gridtravel(r, c));
}

但是當我想用這樣的解決方案降低時間復雜度時,我得到了一個不正確的結果:

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

int gridtravel(int r, int c, int arr[][c]) {
    if (arr[r][c] != 0) return arr[r][c];
    if (arr[c][r] != 0) return arr[c][r];
    if (r == 1 && c == 1) return 1;
    if (r == 0 || c == 0) return 0;
    arr[r][c] = gridtravel(r - 1, c, arr) + gridtravel(r, c - 1, arr);
    return arr[r][c];
}

int main() {
    int r, c;
    scanf("%i%i", &r, &c);
    int arr[r][c];
    for (int i = 0; i <= r; ++i) {
        for (int j = 0; j <= c; ++j) {
            arr[i][j] = 0;
        }
    }
    printf("%i\n", gridtravel(r, c, arr));
}

這里有一些問題:

  • 您的代碼具有未定義的行為,因為初始化循環寫入超出數組末尾: for (int i = 0; i <= r; ++i)應該是for (int i = 0; i < r; ++i) for (int j = 0; j <= c; ++j)應該是for (int j = 0; j < c; ++j) 您也可以將其簡化為memset(arr, 0, sizeof(arr))

  • 此外,您必須將數組維度與單元坐標分開傳遞。

  • 由於您同時訪問arr[r][c]arr[c][r] ,因此必須將數組分配為方陣。

  • 鑒於您使用緩存數組的方式,它應該再分配一行和一列。

  • 如果x大於0 ,您應該利用gridtravel(1,x)gridtravel(x,1)都是1的事實。

這是修改后的版本:

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

int gridtravel(int r, int c, int n, int arr[][n]) {
    if (arr[r][c] != 0) return arr[r][c];
    if (arr[c][r] != 0) return arr[c][r];
    if (r == 0 || c == 0) return 0;
    if (r == 1 || c == 1) return 1;
    return arr[r][c] = gridtravel(r - 1, c, n, arr) + gridtravel(r, c - 1, n, arr);
}

int main() {
    int r, c;
    if (scanf("%i%i", &r, &c) != 2 || r < 1 || c < 1)
        return 1;
    int n = (r > c) ? r + 1 : c + 1;
    int arr[n][n];
    memset(arr, 0, sizeof arr);
    printf("%i\n", gridtravel(r, c, n, arr));
    return 0;
}

主要問題:

  • 的邊界是c-1r-1
  • 你不能交換索引cr
  • 2D arrays 不是那么容易處理的。

如果要使用大數組 malloc 可以比使用堆棧更好。

使用二維數組,您必須將大小作為參數

這里的代碼用 printf 修改后跟隨行程

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

int gridtravel(int n, int r,int c, int (*arr)[n]){
    printf("travel to %d %d\n", r, c);
    if(arr[r][c]!=0) return arr[r][c];
    if(r==1 && c==1) return 1;
    if(r==0 || c==0) return 0;
    
    arr[r][c] = gridtravel(n, r-1, c, arr)+gridtravel(n, r, c-1, arr);
    return arr[r][c];
}

int main(){
    int r,c;
    scanf("%i%i",&r,&c);
    int (*arr)[c] = malloc(sizeof(int[r][c]));
    memset(arr, 0, r*c*sizeof(int));
    printf("%i\n",gridtravel(c, r - 1, c - 1, arr));
    free(arr);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM