八皇后问题(递归回溯)

#include #include int sum = 0; int Danger(int r,int c, int(*a)[8]){ for(int i=0; i<8; i++){ if(a[i][c]) return 0; } for(int i=r,j=c; i>=0&&j>=0; i--,j--){ if(a[i][j]) return 0; } for(int i=r,j=c; i>=0&&j<8; i--,j++){ if(a[i][j]) return 0; } return 1; } /*int Danger(int row, int j, int(*chess)[8]){ int flag1 = 1, flag2 = 1, flag3 = 1, flag4 = 1, flag5 = 1; int ia, ib = 1, ic = 1, id = 1, ie = 1; for(ia = 0; ia < 8; ia++){ if(*(*(chess + ia) + j) == 1){ flag1 = 0; break; }else flag1 = 1; } while((row - ib) != -1 && (j - ib) != -1){ if(*(*(chess + row - ib) + j - ib) == 1){ flag2 = 0; break; }else flag2 = 1; ib++; } while((row + ic) != 8 && (j - ic) != -1){ if(*(*(chess + row + ic) + j - ic) == 1){ flag3 = 0; break; }else flag3 = 1; ic++; } while((row - id) != -1 && (j + id) != 8){ if(*(*(chess + row - id) + j + id) == 1){ flag4 = 0; }else flag4 = 1; id++; } while((row + ie) != 8 && (j + ie) != 8){ if(*(*(chess + row + ie) + j + ie) == 1){ flag5 = 0; break; }else flag5 = 1; ie++; } /* printf("%d", flag1); printf("%d", flag2); printf("%d", flag3); printf("%d", flag4); printf("%d", flag5); printf("\n"); */ //printf("/"); /* if(flag1 && flag2 && flag3 && flag4 && flag5){ return 1; }else return 0; } */ void EQ(int row, int col, int(*chess)[8]){ /* int chess[8][8]; for(int i = 0; i < 8; i++){ for(int j = 0; j < 8; j++){ chess[i][j] = pchess[i][j]; } }*/ if(row == 8){ for(int i = 0; i < 8; i++){ for(int j = 0; j < 8; j++){ printf("%d ", *(*(chess + i) + j)); } printf("\n"); } printf("\n"); ++sum; return; } for(int j = 0; j < 8; j++ ){ if(Danger(row, j, chess) == 1){ *(*(chess + row) + j) = 1; EQ(row + 1, col, chess); *(*(chess + row) + j) = 0; /* for(int i = 0; i < 8; i++){ *(*(chess + row ) + i) = 0; } continue; */ } } }int main(){ int chess[8][8]; for(int i = 0; i < 8; i++){ for(int j = 0; j < 8; j++){ chess[i][j] = 0; } } EQ(0, 8, chess); printf("%d", sum); return 0; }

第一次代码实现的时候,主体逻辑没有考虑清楚,只循环了一轮就输出了,问题在于没有回溯。
for(int j = 0; j < 8; j++ ){ if(Danger(row, j, chess) == 1){ *(*(chess + row) + j) = 1; EQ(row + 1, col, chess); *(*(chess + row) + j) = 0;

回溯 递归到最末行,成功输出后,要抹去原来的位置痕迹。否则会影响Danger函数的判断
*(*(chess + row) + j) = 0;

二维数组和二级指针 【八皇后问题(递归回溯)】第一次代码实现的时候,用二级指针指向二维数组名,出现报错。
因为这两个概念完全不等价,二维数组名不是一个二级指针。
二维数组名是指向一维数组的指针,是一个一级指针 int(*chess)[8]
同理三维数组名是指向二维数组的指针,也是一个一级指针。
多维数组名其实就是一个指向维度-1的数组指针(int(*a)[x][x][x]…)

    推荐阅读