栈-八皇后问题

来源:互联网 发布:js es6 私有属性 编辑:程序博客网 时间:2024/06/15 14:15

问题描述:

八皇后问题是十九世纪著名数学家高斯于1850年提出的。问题是:在8*8的棋盘上摆放8个皇后,使其不能互相攻击,即任意的两个皇后不能处在同意行,同一列,或同意斜线上。可以把八皇后问题拓展为n皇后问题,即在n*n的棋盘上摆放n个皇后,使其任意两个皇后都不能处于同一行、同一列或同一斜线上。

问题分析 :

显然,每一行可以而且必须放一个皇后,所以n皇后问题的解可以用一个n元向量X=(x1,x2,…..xn)表示,其中,1≤ i≤ n且1≤ xi≤ n,即第n个皇后放在第i行第xi列上。

由于两个皇后不能放在同一列上,所以,解向量X必须满足的约束条件为:

xi≠ xj;

若两个皇后的摆放位置分别是(i,xi)和(j,xj),在棋盘上斜率为-1的斜线上,满足条件i-j=xi-xj;在棋盘上斜率为1的斜线上,满足条件i+j=xi+xj;

综合两种情况,由于两个皇后不能位于同一斜线上,所以,

解向量X必须满足的约束条件为:

|i-xi|≠ |j-xj|;

老师要求用栈来写

#include <iostream.h>#include <math.h>#include <windows.h>#define Max 50typedef struct{    int i;    int j;} Elem;typedef struct{    Elem data[Max];    int top;}SqStack;//-------------------------------初始化栈void InitStack(SqStack *&s){    s = (SqStack*)malloc(sizeof(SqStack));    s->top=-1;} //-----------------------------销毁栈void DestroyStack(SqStack*&s){    free(s);}//--------------------------------判断栈是否为空bool StackEmpty(SqStack*s){    return (s->top==-1);} //--------------------------------进栈bool Push(SqStack*&s,Elem e) {    if(s->top==Max-1)    {        return false;    }    s->top++;    s->data[s->top] = e;    return true;}//---------------------------------出栈bool Pop(SqStack*&s , Elem &e) {    if(s->top==-1)    return false;    e = s->data[s->top];    s->top--;    return true;}//-----------------------------------取栈顶元素 bool GetTop(SqStack*s,Elem &e){    if(s->top==-1)    return false;    e = s->data[s->top];    return true;}bool Pan(SqStack *st,int i,int j)//考察皇后的位置是否冲突{    int y,sum;    sum =0;    if(st->top==0)    {        return true;    }    for(y=0;y<=st->top;y++)    {           if(st->data[y].j==j||abs(i - st->data[y].i)==abs(j - st->data[y].j))        {                break;          }        sum++;    }    if(sum==i-1)    {        return true;    }       return false;}int HuangHuo(int n){    SqStack *st;    InitStack(st);    int  x,y,z,t;    Elem e;    e.i = 1;    e.j = 1;    int num = 0;    t = 0;    Push(st,e);    while(1)    {        GetTop(st,e);        int i = e.i;        int j = e.j;        if(i==1&&j>n)//当没有位置可以搜索时,退出        break;          if(e.j>n)        {            Pop(st,e);            Pop(st,e);            e.j++;            Push(st,e);            continue;        }        if(i==n+1&&t)//当栈顶的是最后一行时,输出        {            num++;            printf("结果为:");            for(x=0;x<st->top;x++)             {                printf("(%d,%d)\t",st->data[x].i,st->data[x].j);            }            printf("\n\n");            //Pop(st,e);            Pop(st,e);            e.j++;            Push(st,e);            t = 0;            continue;        }        t=0;        if(Pan(st,i,j))//判断当前位置是否可以放置,break         {            t = 1;        //  printf("栈顶元素可以放置:(%d,%d)\n\n",i,j);            e.i = i+1;            e.j = 1;            Push(st,e);         //  printf("栈顶元素改变:(%d,%d)\n\n",e.i,e.j);            //continue;        }        if(!t)//如果不能放置         {                           //将j位置后移再进栈                         e.j++;            Elem e1;            Pop(st,e1);        //  printf("当前位置不可放置:(%d,%d)\n\n",e1.i,e1.j);            Push(st,e);         //  printf("退栈后进栈的位置:(%d,%d)\n\n",e.i,e.j);        }    }    return num;}int main(){    int n;    printf("请输入皇后的个数:\n");    scanf("%d",&n);    int num = HuangHuo(n);    printf("共有%d放置方法\n",num);    return 0;}

不用栈结构的代码

#include<stdio.h>#include<math.h>int x[100];bool place(int k)//考察皇后k放置在x[k]列是否发生冲突{    int i;    for(i=1;i<k;i++)        if(x[k]==x[i]||abs(k-i)==abs(x[k]-x[i]))            return false;        return true;}void queue(int n){    int i,k;    for(i=1;i<=n;i++)        x[i]=0;    k=1;    while(k>=1)    {        x[k]=x[k]+1;   //在下一列放置第k个皇后        while(x[k]<=n&&!place(k))            x[k]=x[k]+1;//搜索下一列        if(x[k]<=n&&k==n)//得到一个输出        {            for(i=1;i<=n;i++)                printf("%d ",x[i]);            printf("\n");        //return;//若return则只求出其中一种解,若不return则可以继续回溯,求出全部的可能的解        }        else if(x[k]<=n&&k<n)            k=k+1;//放置下一个皇后        else        {            x[k]=0;//重置x[k],回溯            k=k-1;        }    }}void main(){   int n;   printf("输入皇后个数n:\n");   scanf("%d",&n);   queue(n);}
原创粉丝点击