⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 八皇后问题.txt

📁 八皇后问题,C语言
💻 TXT
字号:
八皇后问题

八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 
  高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。 
  对于八皇后问题的实现,如果结合动态的图形演示,则可以使算法的描述更形象、更生动,使教学能产生良好的效果。下面是笔者用Turbo C实现的八皇后问题的图形程序,能够演示全部的92组解。八皇后问题动态图形的实现,主要应解决以下两个问题。 

1.回溯算法的实现 
  (1)为解决这个问题,我们把棋盘的横坐标定为i,纵坐标定为j,i和j的取值范围是从1到8。当某个皇后占了位置(i,j)时,在这个位置的垂直方向、水平方向和斜线方向都不能再放其它皇后了。用语句实现,可定义如下三个整型数组:a[8],b[15],c[24]。其中: 

a[j-1]=1 第j列上无皇后 
a[j-1]=0 第j列上有皇后 
b[i+j-2]=1 (i,j)的对角线(左上至右下)无皇后 
b[i+j-2]=0 (i,j)的对角线(左上至右下)有皇后 
c[i-j+7]=1 (i,j)的对角线(右上至左下)无皇后 
c[i-j+7]=0 (i,j)的对角线(右上至左下)有皇后 

  (2)为第i个皇后选择位置的算法如下: 

for(j=1;j<=8;j++) /*第i个皇后在第j行*/ 
if ((i,j)位置为空)) /*即相应的三个数组的对应元素值为1*/ 
{占用位置(i,j) /*置相应的三个数组对应的元素值为0*/ 
if i<8 
为i+1个皇后选择合适的位置; 
else 输出一个解 
} 

2.图形存取 
  在Turbo C语言中,图形的存取可用如下标准函数实现: 

size=imagesize(x1,y1,x2,y2) ;返回存储区域所需字节数。 
arrow=malloc(size);建立指定大小的动态区域位图,并设定一指针arrow。 
getimage(x1,y1,x2,y2,arrow);将指定区域位图存于一缓冲区。 
putimage(x,y,arrow,copy)将位图置于屏幕上以(x,y)左上角的区域。 

3. 程序清单如下*/ 

#include <graphics.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <dos.h> 
char n[3]={'0','0'};/*用于记录第几组解*/ 
int a[8],b[15],c[24],i; 
int h[8]={127,177,227,277,327,377,427,477};/*每个皇后的行坐标*/ 
int l[8]={252,217,182,147,112,77,42,7};/*每个皇后的列坐标*/ 
void *arrow; 
void try(int i) 
{int j; 
for (j=1;j<=8;j++) 
if (a[j-1]+b[i+j-2]+c[i-j+7]==3) /*如果第i列第j行为空*/ 
{a[j-1]=0;b[i+j-2]=0;c[i-j+7]=0;/*占用第i列第j行*/ 
putimage(h[i-1],l[j-1],arrow,COPY_PUT);/*显示皇后图形*/ 
delay(500);/*延时*/ 
if(i<8) try(i+1); 
else /*输出一组解*/ 
{n[1]++;if (n[1]>'9') {n[0]++;n[1]='0';} 
bar(260,300,390,340);/*显示第n组解*/ 
outtextxy(275,300,n); 
delay(3000); 
} 
a[j-1]=1;b[i+j-2]=1;c[i-j+7]=1; 
putimage(h[i-1],l[j-1],arrow,XOR_PUT);/*消去皇后,继续寻找下一组解*/ 
delay(500); 
} 
} 
int main(void) 
{int gdrive=DETECT,gmode,errorcode; 
unsigned int size; 
initgraph(&gdrive,&gmode,""); 
errorcode=graphresult(); 
if (errorcode!=grOk) 
{printf("Graphics error\n");exit(1);} 
rectangle(50,5,100,40); 
rectangle(60,25,90,33); 
/*画皇冠*/ 
line(60,28,90,28);line(60,25,55,15); 
line(55,15,68,25);line(68,25,68,10); 
line(68,10,75,25);line(75,25,82,10); 
line(82,10,82,25);line(82,25,95,15); 
line(95,15,90,25); 
size=imagesize(52,7,98,38); arrow=malloc(size); 
getimage(52,7,98,38,arrow);/*把皇冠保存到缓冲区*/ 
clearviewport(); 
settextstyle(TRIPLEX_FONT, HORIZ_DIR, 4); 
setusercharsize(3, 1, 1, 1); 
setfillstyle(1,4); 
for (i=0;i<=7;i++) a=1; 
for (i=0;i<=14;i++) b=1; 
for (i=0;i<=23;i++) c=1; 
for (i=0;i<=8;i++) line(125,i*35+5,525,i*35+5);/*画棋盘*/ 
for (i=0;i<=8;i++) line(125+i*50,5,125+i*50,285); 
try(1);/*调用递归函数*/ 
delay(3000); 
closegraph(); 
free(arrow); 
}
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -