/*运用回溯法求解8-Queen问题*/
#include <stdio.h>
#include <math.h>
#include <graphics.h>
static int k,Queen[8][8],a[8];
main()
{
int i=0,j=0;
void Trial();
int drv=DETECT,mode=VGAHI;
initgraph(&drv,&mode,"f://tc/bgi");
clrscr();
Trial(i,j);
closegraph();
return(0);
}
void Trial(int i,int j)
{
int m,n;
void qipan();
if (i==-1)
{printf ("Number of the keys to 8-Queen k=%d",k);
getch();
exit(0);
}
if (i==8)
{
qipan(); /*输出棋盘*/
k=k+1; /*解个数的计数器*/
getch();
clrscr();
Queen[i-1][a[i-1]]=0;
Trial(i-1,a[i-1]+1); /*输出解后,回溯到上一行*/
}
else
{ if (j<8&&Test(i,j)==1)
{ Queen[i][j]=1;
a[i]=j; /*用于记录合法位子棋子的下标*/
Trial(i+1,0);
}
else
{ if(j>7)
{
Queen[i-1][a[i-1]]=0;
Trial(i-1,a[i-1]+1); /*J行均不符要求,回溯上一行*/
}
else
Trial(i,j+1);
}
}
}
int Test(int i,int j)
{
int m,n,p,x,y,safety[8][8];
for (m=0;m<8;m++)
for (n=0;n<8;n++)
safety[m][n]=0; /*初始化*/
for (m=0;m<i;m++)
for (n=0;n<8;n++)
if (Queen[m][n]==1)
{
for (p=0;p<8;p++)
{
safety[p][n]=1; /*行约束*/
safety[m][p]=1; /*列约束*/
}
}
for (m=0;m<i;m++) /*左对角线约束*/
for (n=0;n<8;n++)
if (Queen[m][n]==1)
{
if(m<=n)
for (x=0;x<8-abs(m-n);x++)
{ y=abs(m-n-x);
safety[x][y]=1;
}
else for(x=m-n;x<8;x++)
{ y=abs(m-n-x);
safety[x][y]=1;
}
}
for (m=0;m<i;m++) /*右对角线约束*/
for (n=0;n<8;n++)
if (Queen[m][n]==1)
{
if(m+n<8)
for (x=0;x<=m+n;x++)
{ y=m+n-x;
safety[x][y]=1;
}
else
for(x=m+n-7;x<8;x++)
{ y=m+n-x;
safety[x][y]=1;
}
}
if (safety[i][j]==1)
return (0);
else
return (1);
}
void qipan()
{
int i,j;
setcolor(4);
for(i=0;i<9;i++) /*画棋盘*/
{
line(50,50+i*20,210,50+i*20);
line(50+i*20,50,50+i*20,210);
}
setcolor(0);
for(i=0;i<8;i++) /*画棋子*/
for(j=0;j<8;j++)
if(Queen[i][j]==1)
{
circle(60+i*20,60+j*20,6);
setfillstyle(1,0);
floodfill(60+i*20,60+j*20,0);
}
}
原创:酷酷牛www.cocodiy.com