Фрагмент 8-куин - PullRequest
       5

Фрагмент 8-куин

1 голос
/ 05 сентября 2011

В настоящее время я изучаю откат назад и застрял в проблеме 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;

}

Ответы [ 3 ]

2 голосов
/ 05 сентября 2011

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 элементов столбцов.

edit В ответ на ваш вопрос в комментариях,Вот полная реализация 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)
1 голос
/ 05 сентября 2011

Ваша матрица должна повторяться от 0 до MAX-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;
      }                        
   }
0 голосов
/ 05 сентября 2011

malloc должен вызываться с sizeof (...) * (MAX + 1) как в i-, так и в j-цикле.

Более того, когда я запускал вашу программу, я получил нарушение прав доступа вАнтидиаговая часть in_scacchi (...) из-за того, что код пытается получить доступ к mat [ri] [c + j] , что оценивается как mat [-1] [1] потому что r == 1 и i == 2 .

Таким образом, в вашем описании антидиагональной матрицы, похоже, есть логическая ошибка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...