8皇后片段
我目前正在学习回溯并陷入了 8 皇后问题,我正在使用 8x8 矩阵,我认为我在矩阵传递给函数方面遇到了一些问题,任何帮助将不胜感激。我不介意任何人都会对代码进行任何优化,谢谢。
这是我的代码。
#include <stdio.h>
#include <stdlib.h>
#define MAX 7
//void azzera(int **mat);
void posiziona(int **mat, int r,int c);
void stampa(int **mat);
int in_scacchi(int **mat,int r ,int c);
int main(int argc, char *argv[])
{
int i=0,j=0;
int **mat=(int **)malloc(sizeof(int *)*MAX);
for(i=0;i<=MAX;i++){
mat[i]=(int *)malloc(MAX*sizeof(int));
for(j=0;j<=MAX;j++){
mat[i][j]=-1;
}
}
printf("insert pos of the first queen on the first row (1-8) :");
scanf("%d",&i);
i-=1;
mat[0][i]=1;
posiziona(mat,1,0);
stampa(mat);
system("PAUSE");
return 0;
}
/*void azzera(int **mat){
int i=0,j=0;
for(i=0;i<=MAX;i++){
for(j=0;j<=MAX;j++){
mat[i][j]=-1;
}
}
}*/
void stampa(int **mat){
int i,j;
for(i=0;i<=MAX;i++){
for(j=0;j<=MAX;j++){
printf(" %d",mat[i][j]);
}
printf("\n");
}
}
void posiziona(int **mat, int r,int c){
int i=0,riga=1,flag_col=-1,flag_riga=-1;
if(riga<=7&&flag_riga!=1){
if(flag_riga==1){
flag_riga=-1;
posiziona(mat,r+1,0);
}
else if(in_scacchi(mat,r,c)==1){
if(c==MAX)
posiziona(mat,r-1,0);
posiziona(mat,r,c+1);
}
else{
flag_riga=1;
}
}
}
int in_scacchi(int **mat,int r ,int c){
int i,j,k,m;
int flag=0;
//col
for(i=0;i<r;i++){
for(j=0;j<=c;j++){
if(((mat[i][j]==1)&&(c==j)))
return 1;
}
}
//diag \
for(i=0;i<MAX-r;i++){
for(j=0;j<=MAX-c;j++){
if(mat[MAX-r-i][MAX-c-j]==1)
return 1;
}
}
//antidiag
for(i=r+1;i<=MAX;i++){
for(j=c+1;j<=MAX;j++){
if(mat[r-i][c+j]==1) {
return 1;
}
}
}
return 0;
}
I have currently learning backtracking and got stuck on the 8-queen problem, I am using a 8x8 matrix and I think I've got some problems regarding the matrix passing to functions, any help would be highly apreciated.I wouldn't mind if anyone would bring any optimisation to the code, thanks.
here is my code.
#include <stdio.h>
#include <stdlib.h>
#define MAX 7
//void azzera(int **mat);
void posiziona(int **mat, int r,int c);
void stampa(int **mat);
int in_scacchi(int **mat,int r ,int c);
int main(int argc, char *argv[])
{
int i=0,j=0;
int **mat=(int **)malloc(sizeof(int *)*MAX);
for(i=0;i<=MAX;i++){
mat[i]=(int *)malloc(MAX*sizeof(int));
for(j=0;j<=MAX;j++){
mat[i][j]=-1;
}
}
printf("insert pos of the first queen on the first row (1-8) :");
scanf("%d",&i);
i-=1;
mat[0][i]=1;
posiziona(mat,1,0);
stampa(mat);
system("PAUSE");
return 0;
}
/*void azzera(int **mat){
int i=0,j=0;
for(i=0;i<=MAX;i++){
for(j=0;j<=MAX;j++){
mat[i][j]=-1;
}
}
}*/
void stampa(int **mat){
int i,j;
for(i=0;i<=MAX;i++){
for(j=0;j<=MAX;j++){
printf(" %d",mat[i][j]);
}
printf("\n");
}
}
void posiziona(int **mat, int r,int c){
int i=0,riga=1,flag_col=-1,flag_riga=-1;
if(riga<=7&&flag_riga!=1){
if(flag_riga==1){
flag_riga=-1;
posiziona(mat,r+1,0);
}
else if(in_scacchi(mat,r,c)==1){
if(c==MAX)
posiziona(mat,r-1,0);
posiziona(mat,r,c+1);
}
else{
flag_riga=1;
}
}
}
int in_scacchi(int **mat,int r ,int c){
int i,j,k,m;
int flag=0;
//col
for(i=0;i<r;i++){
for(j=0;j<=c;j++){
if(((mat[i][j]==1)&&(c==j)))
return 1;
}
}
//diag \
for(i=0;i<MAX-r;i++){
for(j=0;j<=MAX-c;j++){
if(mat[MAX-r-i][MAX-c-j]==1)
return 1;
}
}
//antidiag
for(i=r+1;i<=MAX;i++){
for(j=c+1;j<=MAX;j++){
if(mat[r-i][c+j]==1) {
return 1;
}
}
}
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
1. 一个明显的问题是内存分配:
鉴于
MAX
为 7,两个malloc
为矩阵分配的内存太少(七个元素)而不是八个)。老实说,我会将
MAX
重命名为SIZE
或类似的名称,并将所有循环更改为使用严格小于,即我认为这稍微多了惯用且不易出错。
2. 我还没有尝试调试逻辑(我认为期望我们这样做是不公平的)。但是,我注意到除了
main
之外,您没有任何地方可以分配给mat
的元素。对我来说,这表明代码不可能是正确的。3. 除此之外,观察到在有效的解决方案中棋盘的每一行都恰好包含一个皇后可能会很有用。这意味着您实际上并不需要 8x8 矩阵来表示解决方案:列位置的 8 元素数组即可。
编辑为了回答您在评论中提出的问题,这里是一个完整的Python实现,演示了上面的第3点:
1. One glaring problem is the memory allocation:
Given that
MAX
is 7, bothmallocs
are allocating too little memory for the matrix (seven elements instead of eight).To be honest, I'd rename
MAX
toSIZE
or something similar, and change all your loops to use strict less-than, i.e.I would argue that this is slightly more idiomatic and less prone to errors.
2. I haven't tried to debug the logic (I don't think it's fair to expect us to do that). However, I have noticed that nowhere except in
main
do you assign to elements ofmat
. To me this suggests that the code can't possibly be correct.3. Beyond that, it may be useful to observe that in a valid solution every row of the chessboard contains exactly one queen. This means that you don't really need an 8x8 matrix to represent the solution: an 8-element array of column positions will do.
edit In response to your question in the comments, here is a complete Python implementation demonstrating point 3 above:
你的矩阵必须从 0 迭代到 MAX-1,
即
Your matrix must iterate from 0 to MAX-1,
i.e
必须在 i 循环和 j 循环中使用 sizeof(...) * (MAX+1) 调用 malloc。
此外,当我运行你的程序时,我在 in_scacchi(...) 的 antidiag 部分遇到访问冲突,因为代码尝试访问 mat[ri][c+j]计算结果为 mat[-1][1],因为 r==1 和 i==2。
所以你对矩阵反对角线的描述似乎存在逻辑错误。
malloc must be called with sizeof(...) * (MAX+1) in both the i- and j-loop.
Moreover, when I ran your program I got an access violation in the antidiag portion of in_scacchi(...) due to the fact that the code tries to access mat[r-i][c+j] which evaluates to mat[-1][1] because r==1 and i==2.
So there seems to be a logical error in your description of the anti-diagonal of the matrix.