为什么我的代码在这个问题上不能正常工作
Why my code didn't work correct in this problem
网格行程问题
她基本上是递归问题,就是这样:grid travel 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]
。
鉴于您使用缓存数组的方式,它应该多分配一行和一列。
你应该利用 gridtravel(1,x)
和 gridtravel(x,1)
都是 1
如果 x
大于 0
.
这是修改后的版本:
#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-1
和 r-1
- 您不能交换索引
c
和 r
- 二维数组不是那么容易处理的。
如果你想使用大数组 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);
}
网格行程问题
她基本上是递归问题,就是这样:grid travel 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]
。鉴于您使用缓存数组的方式,它应该多分配一行和一列。
你应该利用
gridtravel(1,x)
和gridtravel(x,1)
都是1
如果x
大于0
.
这是修改后的版本:
#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-1
和r-1
- 您不能交换索引
c
和r
- 二维数组不是那么容易处理的。
如果你想使用大数组 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);
}