8-Queens Fronippet
-
26-10-2019 - |
Вопрос
В настоящее время я изучаю переход и застрял на проблеме с 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;
}
Решение
Ваша матрица должна переходить от 0 до макс-1,
т.е.
int **mat= malloc(sizeof(int *)*MAX);
for(i=0;i< MAX;i++){ //see for i<MAX
mat[i]= malloc(MAX*sizeof(int));
for(j=0;j<MAX;j++){ //see for j<MAX
mat[i][j]=-1;
}
}
Другие советы
1. Одна яркая проблема - распределение памяти:
int **mat=(int **)malloc(sizeof(int *)*MAX);
for(i=0;i<=MAX;i++){
mat[i]=(int *)malloc(MAX*sizeof(int));
При условии MAX
7, оба mallocs
выделяют слишком мало памяти для матрицы (семь элементов вместо восемь).
Если честно, я бы переименовал MAX
к SIZE
или что-то подобное, и измените все свои петли, чтобы использовать строгие менее чем, чем, т.е.
for(i = 0; i < SIZE; i++) {
Я бы сказал, что это немного более идиоматическое и менее подверженное ошибкам.
2. Я не пытался отладить логику (я не думаю, что справедливо ожидать, что мы это сделаем). Тем не менее, я заметил, что нигде, кроме как в main
Вы назначаете элементы mat
. Анкет Для меня это говорит о том, что код не может быть правильным.
3. Кроме того, может быть полезно заметить, что в действительном решении каждый ряд шахматной доски содержит ровно одну королеву. Это означает, что вам действительно не нужна матрица 8x8, чтобы представить решение: подойдет 8-элементный массив позиций столбцов.
редактировать В ответ на ваш вопрос в комментариях, вот полная реализация Python, демонстрирующая точку 3 выше:
def can_place(col_positions, col):
row = len(col_positions)
for r, c in enumerate(col_positions):
if c == col or abs(c - col) == abs(r - row): return False
return True
def queens(n, col_positions = []):
if len(col_positions) >= n:
pretty_print(n, col_positions)
return True
for col in xrange(n):
if can_place(col_positions, col):
if queens(n, col_positions + [col]):
return True
return False
def pretty_print(n, col_positions):
for col in col_positions:
print '.' * col + 'X' + '.' * (n - 1 - col)
queens(8)
Malloc должен быть вызван с Sizeof (...) * (max+1) как в I-, так и в J-петле.
Более того, когда я запустил вашу программу, я получил нарушение доступа в антидиагской части in_scacchi (...) из -за того, что код пытается получить доступ Mat [ri] [C+J который оценивает Мат [-1] [1 потому что r == 1 а также i == 2.
Таким образом, кажется, есть логическая ошибка в вашем описании антидиагональной матрицы.