forked from begeekmyfriend/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: begeekmyfriend <[email protected]>
- Loading branch information
1 parent
3b66491
commit b3f2576
Showing
3 changed files
with
178 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,12 @@ | ||
/* | ||
* Copyright (C) 2015, Leo Ma <[email protected]> | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <assert.h> | ||
|
||
static int N; | ||
|
||
static inline int conflict(int *stack, int i, int j) | ||
{ | ||
int k; | ||
for (k = 0; k < i; k++) { | ||
/* If occupied or in one line */ | ||
if (j == stack[k] || abs(i - k) == abs(j - stack[k])) { | ||
return 1; | ||
} | ||
|
@@ -20,110 +15,124 @@ static inline int conflict(int *stack, int i, int j) | |
return 0; | ||
} | ||
|
||
static inline void push(int *stack, int i, int j) | ||
static inline void push(int *stack, int row, int col) | ||
{ | ||
stack[i] = j; | ||
// printf("push %d %d\n", i, j); | ||
stack[row] = col; | ||
} | ||
|
||
static inline int pop(int *stack, int i) | ||
static inline int pop(int *stack, int row) | ||
{ | ||
int j = stack[i]; | ||
stack[i] = -1; | ||
// printf("pop %d %d\n", i, j); | ||
return j; | ||
int col = stack[row]; | ||
stack[row] = -1; | ||
return col; | ||
} | ||
|
||
static inline int top(int *stack) | ||
static inline int top(int *stack, int n) | ||
{ | ||
int i; | ||
for (i = N - 1; i >= 0; i--) { | ||
if (stack[i] != -1) { | ||
return i; | ||
int row; | ||
for (row = n - 1; row >= 0; row--) { | ||
if (stack[row] != -1) { | ||
return row; | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
void show(int *stack) | ||
static char **solution(int *stack, int n) | ||
{ | ||
int i, j; | ||
for (i = 0; i < N; i++) { | ||
for (j = 0; j < N; j++) { | ||
if (j == stack[i]) { | ||
printf("Q"); | ||
} else { | ||
printf("."); | ||
} | ||
int row, col; | ||
char **solution = malloc(n * sizeof(char *)); | ||
for (row = 0; row < n; row++) { | ||
char *line = malloc(n + 1); | ||
for (col = 0; col < n; col++) { | ||
line[col] = col == stack[row] ? 'Q' : '.'; | ||
} | ||
printf("\n"); | ||
line[n] = '\0'; | ||
solution[row] = line; | ||
} | ||
return solution; | ||
} | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
int i, j, sum = 0; | ||
int *stack; | ||
|
||
if (argc != 2) { | ||
printf("Usage: ./queen 8\n"); | ||
exit(-1); | ||
} | ||
|
||
N = atoi(argv[1]); | ||
if (N <= 0) { | ||
exit(0); | ||
/** | ||
** Return an array of arrays of size *returnSize. | ||
** Note: The returned array must be malloced, assume caller calls free(). | ||
**/ | ||
char*** solveNQueens(int n, int *returnSize) { | ||
int row = 0, col = 0, sum = 0; | ||
char ***solutions = malloc(1000 * sizeof(char **)); | ||
|
||
int *stack = malloc(n * sizeof(int)); | ||
for (row = 0; row < n; row++) { | ||
stack[row] = -1; | ||
} | ||
|
||
stack = malloc(N * sizeof(*stack)); | ||
if (stack == NULL) { | ||
exit(-1); | ||
} | ||
|
||
if (N == 1) { | ||
if (n == 1) { | ||
stack[0] = 0; | ||
show(stack); | ||
printf("This is the %dth solution.\n", ++sum); | ||
exit(0); | ||
} | ||
|
||
for (i = 0; i < N; i++) { | ||
stack[i] = -1; | ||
solutions[0] = solution(stack, n); | ||
*returnSize = 1; | ||
return solutions; | ||
} | ||
|
||
i = j = 0; | ||
for (; ;) { | ||
for (; i < N; i++) { | ||
while (j < N) { | ||
if (conflict(stack, i, j)) { | ||
while (j == N - 1) { | ||
/* No space for row[i] so backtracking is needed */ | ||
if (--i < 0) { | ||
for (; row < n; row++) { | ||
while (col < n) { | ||
if (conflict(stack, row, col)) { | ||
while (col == n - 1) { | ||
/* No other positions in this row and therefore backtracking */ | ||
if (--row < 0) { | ||
/* All solution provided */ | ||
free(stack); | ||
exit(0); | ||
*returnSize = sum; | ||
return solutions; | ||
} | ||
j = pop(stack, i); | ||
col = pop(stack, row); | ||
} | ||
j++; | ||
col++; | ||
} else { | ||
push(stack, i, j); | ||
push(stack, row, col); | ||
break; | ||
} | ||
} | ||
j = 0; | ||
col = 0; | ||
} | ||
|
||
i = top(stack); | ||
if (i == N - 1) { | ||
show(stack); | ||
printf("This is the %dth solution.\n", ++sum); | ||
/* Full stack, a new complete solution */ | ||
row = top(stack, n); | ||
if (row == n - 1) { | ||
solutions[sum++] = solution(stack, n); | ||
} | ||
|
||
j = pop(stack, i); | ||
j++; | ||
/* Move on to find if there are still other solutions */ | ||
col = pop(stack, row); | ||
col++; | ||
} | ||
|
||
assert(0); | ||
} | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
int i, n, row, col, num_of_solution; | ||
|
||
if (argc != 2) { | ||
printf("Usage: ./queen 8\n"); | ||
exit(-1); | ||
} | ||
|
||
n = atoi(argv[1]); | ||
char ***solutions = solveNQueens(n, &num_of_solution); | ||
for (i = 0; i < num_of_solution; i++) { | ||
char **solution = solutions[i]; | ||
for (row = 0; row < n; row++) { | ||
char *line = solution[row]; | ||
for (col = 0; col < n; col++) { | ||
putchar(line[col]); | ||
} | ||
putchar('\n'); | ||
} | ||
printf("The %dth solution.\n", i + 1); | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
all: | ||
gcc -O2 -o queen n_queens.c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <assert.h> | ||
static inline int conflict(int *stack, int i, int j) | ||
{ | ||
int k; | ||
for (k = 0; k < i; k++) { | ||
/* If occupied or in one line */ | ||
if (j == stack[k] || abs(i - k) == abs(j - stack[k])) { | ||
return 1; | ||
} | ||
} | ||
return 0; | ||
} | ||
|
||
static inline void push(int *stack, int row, int col) | ||
{ | ||
stack[row] = col; | ||
} | ||
|
||
static inline int pop(int *stack, int row) | ||
{ | ||
int col = stack[row]; | ||
stack[row] = -1; | ||
return col; | ||
} | ||
|
||
static inline int top(int *stack, int n) | ||
{ | ||
int row; | ||
for (row = n - 1; row >= 0; row--) { | ||
if (stack[row] != -1) { | ||
return row; | ||
} | ||
} | ||
return 0; | ||
} | ||
|
||
int totalNQueens(int n) { | ||
int row = 0, col = 0, sum = 0, cap = 1; | ||
int *stack = malloc(n * sizeof(int)); | ||
for (row = 0; row < n; row++) { | ||
stack[row] = -1; | ||
} | ||
|
||
if (n == 1) { | ||
return 1; | ||
} | ||
|
||
for (; ;) { | ||
for (; row < n; row++) { | ||
while (col < n) { | ||
if (conflict(stack, row, col)) { | ||
while (col == n - 1) { | ||
/* No other positions in this row and therefore backtracking */ | ||
if (--row < 0) { | ||
/* All solution provided */ | ||
free(stack); | ||
return sum; | ||
} | ||
col = pop(stack, row); | ||
} | ||
col++; | ||
} else { | ||
push(stack, row, col); | ||
break; | ||
} | ||
} | ||
col = 0; | ||
} | ||
|
||
/* Full stack, a new complete solution */ | ||
row = top(stack, n); | ||
if (row == n - 1) { | ||
sum++; | ||
} | ||
|
||
/* Move on to find if there are still other solutions */ | ||
col = pop(stack, row); | ||
col++; | ||
} | ||
} | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
if (argc != 2) { | ||
printf("Usage: ./queen 8\n"); | ||
exit(-1); | ||
} | ||
|
||
int n = atoi(argv[1]); | ||
printf("Total %d solution for %d queens.\n", totalNQueens(n), n); | ||
return 0; | ||
} |