63,594
社区成员




/* Print the results at the end of the run */
void printResults(time_t* pt1, time_t* pt2)
{
double secs;
int hours , mins, intsecs;
printf("End: \t%s", ctime(pt2));
secs = difftime(*pt2, *pt1);
intsecs = (int)secs;
printf("Calculations took %d second%s.\n", intsecs, (intsecs == 1 ? "" : "s"));
/* Print hours, minutes, seconds */
hours = intsecs/3600;
intsecs -= hours * 3600;
mins = intsecs/60;
intsecs -= mins * 60;
if (hours > 0 || mins > 0)
{
printf("Equals ");
if (hours > 0)
{
printf("%d hour%s, ", hours, (hours == 1) ? "" : "s");
}
if (mins > 0)
{
printf("%d minute%s and ", mins, (mins == 1) ? "" : "s");
}
printf("%d second%s.\n", intsecs, (intsecs == 1 ? "" : "s"));
}
}
/* main routine for N Queens program.*/
int main(int argc, char** argv)
{
time_t t1, t2;
int boardsize;
if (argc != 2) {
printf("N Queens program by Jeff Somers.\n");
printf("\tallagash98@yahoo.com or jsomers@alumni.williams.edu\n");
printf("This program calculates the total number of solutions to the N Queens problem.\n");
printf("Usage: nq <width of board>\n"); /* user must pass in size of board */
return 0;
}
boardsize = atoi(argv[1]);
/* check size of board is within correct range */
if (MIN_BOARDSIZE > boardsize || MAX_BOARDSIZE < boardsize)
{
printf("Width of board must be between %d and %d, inclusive.\n",
MIN_BOARDSIZE, MAX_BOARDSIZE );
return 0;
}
time(&t1);
printf("N Queens program by Jeff Somers.\n");
printf("\tallagash98@yahoo.com or jsomers@alumni.williams.edu\n");
printf("Start: \t %s", ctime(&t1));
Nqueen(boardsize); /* find solutions */
time(&t2);
printResults(&t1, &t2);
if (g_numsolutions != 0)
{
#ifdef WIN32
printf("For board size %d, %I64d solution%s found.\n", boardsize, g_numsolutions, (g_numsolutions == 1 ? "" : "s"));
#else
printf("For board size %d, %d solution%s found.\n", boardsize, g_numsolutions, (g_numsolutions == 1 ? "" : "s"));
#endif
}
else
{
printf("No solutions found.\n");
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef WIN32
#define MAX_BOARDSIZE 21
typedef unsigned __int64 SOLUTIONTYPE;
#else
#define MAX_BOARDSIZE 18
typedef unsigned long SOLUTIONTYPE;
#endif
#define MIN_BOARDSIZE 2
SOLUTIONTYPE g_numsolutions = 0;
/* Print a chess table with queens positioned for a solution */
/* This is not a critical path function & I didn't try to optimize it. */
void printtable(int boardsize, int* aQueenBitRes, SOLUTIONTYPE numSolution)
{
int i, j, k, row;
/* We only calculated half the solutions, because we can derive
the other half by reflecting the solution across the "Y axis". */
for (k = 0; k < 2; ++k)
{
#ifdef WIN32
printf("*** Solution #: %I64d ***\n", 2 * numSolution + k - 1);
#else
printf("*** Solution #: %d ***\n", 2 * numSolution + k - 1);
#endif
for ( i = 0; i < boardsize; i++)
{
unsigned int bitf;
/*
Get the column that was set (i.e. find the
first, least significant, bit set).
If aQueenBitRes[i] = 011010b, then
bitf = 000010b
*/
bitf = aQueenBitRes[i];
row = bitf ^ (bitf & (bitf - 1)); /* get least significant bit */
for ( j = 0; j < boardsize; j++)
{
/* keep shifting row over to the right until we find the one '1' in
the binary representation. There will only be one '1'. */
if (0 == k && ((row >> j) & 1))
{
printf("Q ");
}
else if (1 == k && (row & (1 << (boardsize - j - 1)))) /* this is the board reflected across the "Y axis" */
{
printf("Q ");
}
else
{
printf(". ");
}
}
printf("\n");
}
printf("\n");
}
}
void Nqueen(int board_size)
{
int aQueenBitRes[MAX_BOARDSIZE]; /* results */
int aQueenBitCol[MAX_BOARDSIZE]; /* marks colummns which already have queens */
int aQueenBitPosDiag[MAX_BOARDSIZE]; /* marks "positive diagonals" which already have queens */
int aQueenBitNegDiag[MAX_BOARDSIZE]; /* marks "negative diagonals" which already have queens */
int aStack[MAX_BOARDSIZE + 2]; /* we use a stack instead of recursion */
register int* pnStack;
register int numrows = 0; /* numrows redundant - could use stack */
register unsigned int lsb; /* least significant bit */
register unsigned int bitfield; /* bits which are set mark possible positions for a queen */
int i;
int odd = board_size & 1; /* 0 if board_size even, 1 if odd */
int board_minus = board_size - 1; /* board size - 1 */
int mask = (1 << board_size) - 1; /* if board size is N, mask consists of N 1's */
/* Initialize stack */
aStack[0] = -1; /* set sentinel -- signifies end of stack */
/* NOTE: (board_size & 1) is true iff board_size is odd */
/* We need to loop through 2x if board_size is odd */
for (i = 0; i < (1 + odd); ++i)
{
/* We don't have to optimize this part; it ain't the
critical loop */
bitfield = 0;
if (0 == i)
{
/* Handle half of the board, except the middle
column. So if the board is 5 x 5, the first
row will be: 00011, since we're not worrying
about placing a queen in the center column (yet).
*/
int half = board_size>>1; /* divide by two */
/* fill in rightmost 1's in bitfield for half of board_size
If board_size is 7, half of that is 3 (we're discarding the remainder)
and bitfield will be set to 111 in binary. */
bitfield = (1 << half) - 1;
pnStack = aStack + 1; /* stack pointer */
aQueenBitRes[0] = 0;
aQueenBitCol[0] = aQueenBitPosDiag[0] = aQueenBitNegDiag[0] = 0;
}
else
{
/* Handle the middle column (of a odd-sized board).
Set middle column bit to 1, then set
half of next row.
So we're processing first row (one element) & half of next.
So if the board is 5 x 5, the first row will be: 00100, and
the next row will be 00011.
*/
bitfield = 1 << (board_size >> 1);
numrows = 1; /* prob. already 0 */
/* The first row just has one queen (in the middle column).*/
aQueenBitRes[0] = bitfield;
aQueenBitCol[0] = aQueenBitPosDiag[0] = aQueenBitNegDiag[0] = 0;
aQueenBitCol[1] = bitfield;
/* Now do the next row. Only set bits in half of it, because we'll
flip the results over the "Y-axis". */
aQueenBitNegDiag[1] = (bitfield >> 1);
aQueenBitPosDiag[1] = (bitfield << 1);
pnStack = aStack + 1; /* stack pointer */
*pnStack++ = 0; /* we're done w/ this row -- only 1 element & we've done it */
bitfield = (bitfield - 1) >> 1; /* bitfield -1 is all 1's to the left of the single 1 */
}
/* this is the critical loop */
for (;;)
{
/* could use
lsb = bitfield ^ (bitfield & (bitfield -1));
to get first (least sig) "1" bit, but that's slower. */
lsb = -((signed)bitfield) & bitfield; /* this assumes a 2's complement architecture */
if (0 == bitfield)
{
bitfield = *--pnStack; /* get prev. bitfield from stack */
if (pnStack == aStack) { /* if sentinel hit.... */
break ;
}
--numrows;
continue;
}
bitfield &= ~lsb; /* toggle off this bit so we don't try it again */
aQueenBitRes[numrows] = lsb; /* save the result */
if (numrows < board_minus) /* we still have more rows to process? */
{
int n = numrows++;
aQueenBitCol[numrows] = aQueenBitCol[n] | lsb;
aQueenBitNegDiag[numrows] = (aQueenBitNegDiag[n] | lsb) >> 1;
aQueenBitPosDiag[numrows] = (aQueenBitPosDiag[n] | lsb) << 1;
*pnStack++ = bitfield;
/* We can't consider positions for the queen which are in the same
column, same positive diagonal, or same negative diagonal as another
queen already on the board. */
bitfield = mask & ~(aQueenBitCol[numrows] | aQueenBitNegDiag[numrows] | aQueenBitPosDiag[numrows]);
continue;
}
else
{
/* We have no more rows to process; we found a solution. */
/* Comment out the call to printtable in order to print the solutions as board position*/
/* printtable(board_size, aQueenBitRes, g_numsolutions + 1); */
++g_numsolutions;
bitfield = *--pnStack;
--numrows;
continue;
}
}
}
/* multiply solutions by two, to count mirror images */
g_numsolutions *= 2;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
long sum = 0, upperlim = 1;
void test(long row, long ld, long rd)
{
if (row != upperlim)
{
long pos = upperlim & ~(row | ld | rd);
while (pos)
{
long p = pos & -pos;
pos -= p;
test(row + p, (ld + p) << 1, (rd + p) >> 1);
}
} else
sum++;
}
int main(int argc, char *argv[])
{
time_t tm;
int n = 16;
if (argc != 1)
n = atoi(argv[1]);
tm = time(0);
if ((n < 1) || (n > 32))
{
printf(" 只能计算1-32之间\n");
exit(-1);
}
printf("%d 皇后\n", n);
upperlim = (upperlim << n) - 1;
test(0, 0, 0);
printf("共有%ld种排列, 计算时间%d秒 \n", sum, (int) (time(0) - tm));
}
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
void input(char chess[][8], int n, FILE *);
int Trial(int i, FILE *);
int judge(int *pj, int i, int j);
int row_number[8];//此数组用来存放数组下标对应行放置的棋子所在的列号
//(如row_number[0]就是存放的0行所放棋子的列号)
int cout = 0;//此全局变量cout用来统计一共有多少种符合要求的情况
char chessboard[8][8] = {'o','o','o','o','o','o','o','o',
'o','o','o','o','o','o','o','o',
'o','o','o','o','o','o','o','o',
'o','o','o','o','o','o','o','o',
'o','o','o','o','o','o','o','o',
'o','o','o','o','o','o','o','o',
'o','o','o','o','o','o','o','o',
'o','o','o','o','o','o','o','o'};
int _tmain(int argc, _TCHAR* argv[])
{
FILE *fp = NULL;
if((fp = fopen("八皇后问题.txt", "w")) == NULL)
{
perror("八皇后问题");
exit(0);
}
int total = Trial(0, fp);
fprintf(fp, "\n八皇后问题共有%d种符合要求的情况\n", total);
printf("八皇后问题的%d种符合条件的情况均写入到文件中\n", total);
return 0;
}
int Trial(int i, FILE *fp_trial)
{
if(i > 7)
{
input(chessboard, 8, fp_trial);
fputc('\n', fp_trial);
cout++;
}
else
for(int j = 0; j < 8; ++j)
{
chessboard[i][j] = '*';//在第i行第j列处放置一颗棋子
if(judge(row_number, i, j))
{//合法则放下一个棋子并且将此列序号存入数组cj中
row_number[i] = j;//第i行第j列处放置的棋子合法则将该棋子所在列号j值存放进数组中
Trial(i + 1,fp_trial);
}
chessboard[i][j] = 'o';//清除第i行第j列处的棋子
}
return cout;
}
int judge(int *prow, int i, int j)
{//判断当前放置的棋子是否合法(不合法返回0合法返回1)
for(int n = 0; n < i; n++)
{//将当前行放置棋子的位置与前每一行放置棋子的位置进行比较
//比较方法是首先看它们是否在同一列,不在则看它们是否在一条主对角线上,
//还不在则看它们是否在一条副对角线上。
int *p = prow;
p += n;
if((*p == j) || ((j - i) == (*p - n)) || ((j + i) == (*p + n)))
return 0;
}
return 1;
}
void input(char chess[][8], int n, FILE *fp_input)
{//打印出棋盘状态
for(int i = 0; i < 8; i++)
{
for(int j = 0; j < n; j++)
fprintf(fp_input, "%c ", chess[i][j]);
fputc('\n', fp_input);
}
}
#include "stdafx.h"
#include "iostream.h"
#include "string.h"
#define COL 8
void SetQueen(int low, int n);
void OutputResult(void);
int IsCorrect(int col, int row);
char Status[COL + 1][COL + 1];
int AnsID = 0;
int main(int argc, char* argv[])
{
memset(Status, 0, sizeof(Status));
AnsID = 0;
SetQueen(1, COL);
return 0;
}
void SetQueen(int low, int n)
{
int j;
if (low > n)
{
OutputResult();
}
else
{
for (j = 1; j <= n; j++)
{
Status[low][j] = 1;
if (IsCorrect(low, j))
{
SetQueen(low + 1, n);
}
Status[low][j] = 0;
}
}
}
void OutputResult(void)
{
int i, j;
AnsID++;
cout << "\n";
cout << "The " << AnsID << " Answer:" << "\n\n";
for (i = 1; i < COL + 1; i++)
{
for (j = 1; j < COL + 1; j++)
{
if (Status[i][j])
{
cout << "O " ;
}
else
{
cout << "X ";
}
}
cout << "\n";
}
}
int IsCorrect(int col, int row)
{
int i, j;
for (i = 1; i < COL + 1; i++)
{
if ((Status[col][i] == 1) && (i != row))
{
return 0;
}
}
for (i = 1; i < COL + 1; i++)
{
if ((Status[i][row] == 1) && (i != col))
{
return 0;
}
}
for (i = col + 1, j = row + 1; (i < COL + 1 && j < COL + 1); i++, j++)
{
if (Status[i][j] == 1)
{
return 0;
}
}
for (i = col -1, j = row - 1; (i >= 1 && j >= 1); i--, j--)
{
if (Status[i][j] == 1)
{
return 0;
}
}
for (i = col + 1, j = row - 1; (i < COL + 1 && j >= 1); i++, j--)
{
if (Status[i][j] == 1)
{
return 0;
}
}
for (i = col -1, j = row + 1; (i >= 1 && j <= COL + 1); i--, j++)
{
if (Status[i][j] == 1)
{
return 0;
}
}
return 1;
}