33,010
社区成员
发帖
与我相关
我的任务
分享
/*
*
日期:2008-11-9下午
函数功能:已知在N*N的方格内,摆上不同的“皇后”(国际象棋),使其不在同一行、同一列、同一对角线
,求出所有的解 当N=4时,输出2组解;当N=8时,输出92组解
算法:回溯法
*/
#include "stdio.h"
#include "math.h"
#define N 8 /*皇后数*/
#define DEBUG 1
void init(void);
void backtrack(int num);
void showAnswer(void);
int state[N][N]; /*棋盘状态*/
long count=0; /*组解计数器*/
main()
{
clrscr();
init();
backtrack(0);
getch();
}
void init(void)
{
int i,j;
for (i=0;i<N;i++)
for (j=0;j<N;j++)
state[i][j]=0;
}
void backtrack(int num) /*以行作为判断点*/
{
int row,earse;
if ( num==N )
{
count++;
showAnswer();
}
else
{
for (row=0;row<N;row++)
if ( isSafe(num,row) )
{
for (earse=0;earse<N;earse++) /*一行只能放一个皇后*/
state[num][earse]=0;
state[num][row]=1; /*1表示该点皇后被放置*/
backtrack(num+1); /*该点安全,回溯*/
}
}
}
void showAnswer(void)
{
int i,j;
printf("No.%ld\n",count);
for (i=0;i<N;i++)
{
for (j=0;j<N;j++)
{
if(state[i][j]==0) printf("%3s",".");
if(state[i][j]==1) printf("%3s","Q");
}
printf("\n");
}
}
/*
*判断该点是否安全
*/
int isSafe(int num,int row)
{
int i,j;
for (i=0;i<num;i++)
{
for(j=0;j<N;j++)
if( state[i][j]==1)
if ( abs(i-num)==abs(j-row)||j==row ) return 0;
}
return 1;
}
#define QUEENS (8)
int upperlim = (1<<QUEENS) - 1;
int sum = 0;
void test(int row, int ld, int rd)
{
int pos, p;
if(row != upperlim)
{
pos = upperlim & (~(row|ld|rd));
while(pos != 0)
{
p = pos & (-pos);
pos = pos - p;
test(row+p, (ld+p)<<1, (rd+p)>>1);
}
}
else
{
sum++;
}
}
//test(0, 0, 0);