实验题目
编写一个程序exp3-6.cpp,求解皇后问题:在n×n的方格棋盘上,放置n个皇后,要求每个皇后不同行、不同列、不同左右对角线。
要求:(1)皇后的个数n由用户输入,其值不能超过20,输出所有的解。(2)采用类似于栈求解迷宫问题的方法。
实验步骤
(包括基本设计思路、算法设计、函数相关说明、输入与输出以及程序运行结果)
基本设计思路:回朔思想。
算法设计:定义一个栈sqstack,用于表示皇后棋盘的行数,定义一个一维数组向x[]=0,用于存储棋盘中的列数(一维数组可以直接防止皇后同行),每到一行,取栈顶元素e,x[e]++;然后判断是否能放皇后,行则入栈一次,接着再次取栈顶元素,x[e]归零,不行则x[e]++,直至x[e]增加加到n。如果该行都不能放皇后,则出栈一次,接着取栈顶元素,继续上述过程。最后栈空时退出。
函数相关说明:void queens(int *x,intn,sqstack *&s);//进行回朔的过程
int judge(int *x,int k);//判断是否能放皇后
//只要有某行(第i行)皇后与这个第k行的皇后处在同一列(x[i]=x[k])或者处在同一斜线(|i-k|=|x[i]-x[k]|),则立即返回假(0)
void print(int *x,int n);//打印结果函数
void initstack(sqstack*&s);//初始化栈,其中,将栈数据项全部赋值为1,2...20
void push(sqstack *&s);//进栈
void pop(sqstack *&s);//出栈
void gettop(sqstack *s,int&e);//取栈顶元素
bool stackempty(sqstack *s);判断栈是否为空
输入:4,5,10
输出:见运行图。
运行结果:
实验心得体会
通过这次实验,复习了回朔的解题方法,以及如何用栈解决问题,进一步熟悉了栈的使用。
源程序清单(代码)#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <malloc.h>
using namespace std;
typedef struct
{
int k[21];
int top;
} sqstack;
void queens(int *x,int n,sqstack *&s);
int judge(int *x,int k);
void print(int *x,int n);
void initstack(sqstack *&s);
void push(sqstack *&s);
void pop(sqstack *&s);
void gettop(sqstack *s,int &e);
bool stackempty(sqstack *s);
int main()
{
sqstack *s;
int n;
int *x;
initstack(s);
scanf("%d",&n);
x=(int *)malloc(sizeof(int)*(n+1));
queens(x,n,s);
return 0;
}
int judge(int *x,int k)
{
int i;
for(i=1; i<k; i++)
{
if((x[i]==x[k])||(fabs(x[i]-x[k])==fabs(i-k)))
return 0;
}
return 1;
}
void queens(int *x,int n,sqstack *&s)
{
int e,i=1;
push(s);
gettop(s,e);//进栈一次
x[e]=0;
while(!stackempty(s))//栈不为空
{
x[e]++;
while(x[e]<=n&&!judge(x,e))
x[e]++;
if(x[e]<=n)
{
if(e==n)
{
printf("第%d个解:",i);
print(x,e);
i++;}
else
{
push(s);
gettop(s,e);//进栈
x[e]=0;
}
}
else
{
pop(s);
gettop(s,e);//出栈
}
}
}
void print(int *x,int n)
{
int i;
for(i=1; i<=n; i++)
{
if(i==n)
printf("%d",x[i]);
else
printf("%d ",x[i]);
}
printf("\n");
}
void initstack(sqstack *&s)
{
s=(sqstack *)malloc(sizeof(sqstack));
int i;
for(i=0; i<21; i++)
s->k[i]=i+1;
s->top=-1;
}
void push(sqstack *&s)
{
s->top++;
}
void pop(sqstack *&s)
{
s->top--;
}
void gettop(sqstack *s,int &e)
{
e=s->k[s->top];
}
bool stackempty(sqstack *s)
{
return(s->top==-1);
}