-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnqueenss.c
More file actions
178 lines (149 loc) · 5.12 KB
/
nqueenss.c
File metadata and controls
178 lines (149 loc) · 5.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#include "nqueens.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*
Versão sequencial do trabalho 1
*/
//variável compartilhada
unsigned long long soma = 0;
int **alocaTabuleiro(int dim);
void inicializaTabuleiro(int **tab, int dim);
void liberaTabuleiro(int **tab,int dim);
void imprimeTabuleiro(int **tab,int dim);
int verificaPosicao(int **tab,int dim,int lin,int cont);
unsigned long long calculaPos(int **tab,int dim,int queens);
int posicionaRainha(int **tab,int dim,int queens,int lin,int contQ);
unsigned long long nqueens(int dim,int queens);
/* Função que retorna a soma das posições da rainhas em cada umas das soluções */
unsigned long long nqueens(int dim,int queens){
int **tab;
soma = 0;
//verifica foram passados parametros invalidos
if(queens == 0 || dim < 1 || queens > dim){
return 0; //parametro invalido
}
tab = alocaTabuleiro(dim); //aloca espaco de memoria para o tabuleiro
if(tab == NULL){
exit(1);
}
inicializaTabuleiro(tab,dim); //inicializa posições do tabuleiro com zero
posicionaRainha(tab,dim,queens,0,0); //acha as soluções possiveis e calcula a soma das posições
liberaTabuleiro(tab,dim); //desaloca a memoria alocada para o tabuleiro
return soma; // retorna a soma das posições que a rainha(s) pode assumir em todas as soluções possiveis
}
/* Função que posiciona a rainha no tabuleiro e faz o calculo das posições possiveis */
int posicionaRainha(int **tab,int dim,int queens,int lin,int contQ){
int i,j;
if(contQ == queens){ //verifica se já inseriu a quantidade de rainhas desejada
if(queens==1){ //verifica se apenas uma rainha estar sendo inserida
soma = calculaPos(tab,dim,queens);
}else{ //caso tenha mais de uma rainha sendo inserida
soma += calculaPos(tab,dim,queens);
}
}
for(i = lin; i < dim; ++i){
for(j = 0; j < dim; ++j){
if(verificaPosicao(tab,dim,i,j)){ //verifica se a posição é valida
tab[i][j] = 1; //posiciona a rainha no tabuleiro
if(posicionaRainha(tab,dim,queens,i+1,contQ+1)){ //usa recursão para inserir o resto das rainhas
return 1;
}else{
tab[i][j] = 0; //se não leva a uma solução remove a rainha
}
}
}
}
return 0;
}
/* Função que realiza o calculo de todas as posições que levam a alguma solução */
unsigned long long calculaPos(int **tab,int dim,int queens){
int i, j, cont = 0;
unsigned long long somaPos = 0;
for (i = 0; i < dim; ++i){
for (j = 0; j < dim; ++j){
if(tab[i][j]){
if(queens==1){ //caso apenas uma rainha esteja sendo inserida no tabuleiro
somaPos = pow(2,pow(dim,2))-1;
}
else{
somaPos += pow(2, cont); //calcula a posição da rainha em cada solução
}
}
cont++; //incrementa casa do tabuleiro
}
}
return somaPos;
}
/* Função que verifica se a rainha estar sendo inserida em uma posição valida*/
int verificaPosicao(int **tab,int dim,int lin,int col){
int i, j;
for(j = 0; j < col; ++j){
if(tab[lin][j]){ //verifica se exista alguma rainha na mesma linha
return 0; //posição invalida
}
}
for(i = 0; i < lin; ++i){
if(tab[i][col]){ //verifica se existe alguma rainha na mesma coluna
return 0; //posicao invalida
}
}
for(i = lin, j = col; i >= 0 && j >= 0; --i,--j){
if(tab[i][j]){ //verifica se exista alguma rainha na diagonal superior
return 0; //posicao invalida
}
}
for(i = lin, j = col; i >= 0 && j < dim; --i,++j){
if(tab[i][j]){ //verifica se existe alguma rainha na diagonal inferior
return 0; //posicao invalida
}
}
return 1; //estar inserindo em uma posicao valida
}
/* Função que aloca espaço de memoria para a criação do tabuleiro */
int **alocaTabuleiro(int dim){
int i;
int **tab = (int **)calloc(dim, sizeof(int *));
if(tab==NULL){
return NULL;
}
for(i = 0; i < dim; ++i){
tab[i] = (int *)calloc(dim, sizeof(int *));
if(tab[i]==NULL){
return NULL;
}
}
return tab;
}
/* Função que inicializa o tabuleiro */
void inicializaTabuleiro(int **tab, int dim){
int lin,col;
for(lin = 0; lin < dim; ++lin){
for(col = 0; col < dim; ++col){
tab[lin][col] = 0;
}
}
}
/* Função que imprime o tabuleiro*/
void imprimeTabuleiro(int **tab,int dim){
int lin,col;
for(lin = 0; lin < dim; ++lin){
for(col = 0; col < dim; ++col){
if(tab[lin][col]){
printf("X ");
}else{
printf("0 ");
}
}
printf("\n");
}
printf("\n");
}
/* Função que desaloca a memoria alocada para o tabuleiro */
void liberaTabuleiro(int **tab,int dim){
int i;
for(i = 0; i < dim; ++i){
free(tab[i]);
}
free(tab);
}