# 八女王问题如何解？

...全文
138 10 打赏 收藏 转发到动态 举报

10 条回复

popyy0101 2008-04-01
• 打赏
• 举报

Mnky 2008-03-31
• 打赏
• 举报

``````
/* 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);

/* 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;
}
``````
Mnky 2008-03-31
• 打赏
• 举报

``````

#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 = -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;
aQueenBitCol = aQueenBitPosDiag = aQueenBitNegDiag = 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 = bitfield;
aQueenBitCol = aQueenBitPosDiag = aQueenBitNegDiag = 0;
aQueenBitCol = bitfield;

/* Now do the next row.  Only set bits in half of it, because we'll
flip the results over the "Y-axis".  */
aQueenBitNegDiag = (bitfield >> 1);
aQueenBitPosDiag = (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;
}

``````
Mnky 2008-03-31
• 打赏
• 举报

``````
#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);
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));
}
``````
ayanamiliu 2008-03-31
• 打赏
• 举报

4楼是用visual studio 2008 写的吧，这个要包含一些预编译文件，不然不能运行，最起码要
#defint _tmain wmi
mengjunyi 2008-03-29
• 打赏
• 举报

-________-b
i_coding 2008-03-29
• 打赏
• 举报

``````
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>

void input(char chess[], int n, FILE *);
int Trial(int i, FILE *);
int judge(int *pj, int i, int j);

int row_number;//此数组用来存放数组下标对应行放置的棋子所在的列号
//(如row_number就是存放的0行所放棋子的列号)
int cout = 0;//此全局变量cout用来统计一共有多少种符合要求的情况
char chessboard =    {'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[], 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);
}
}

``````
ding1188 2008-03-29
• 打赏
• 举报

[Quote=引用 2 楼 abupie 的回复:]
baidu好。
[/Quote]
hastings 2008-03-29
• 打赏
• 举报

LZ偷懒,我也偷懒,哈,哈,百度的(不知正确否):
``````#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;

}`````` 算法1-女王问题
C语言常用算法-女王问题 empress和queen区别_女王英文如何表达 原来扑克牌和女王也有关吗 大白话HMM全套系列课程--从此爱上HMM MySQL如何除外键约束遇到的问题和原因
MySQL如何除外键约束遇到的问题和原因 数论及其应用——素数问题

63,594 发帖 与我相关 我的任务
c++ 技术论坛（原bbs） • 近7日
• 近30日
• 至今

1. 请不要发布与C++技术无关的贴子
2. 请不要发布与技术无关的招聘、广告的帖子
3. 请尽可能的描述清楚你的问题，如果涉及到代码请尽可能的格式化一下