您的位置:程序门 -> c/c++ -> 新手乐园



八皇后问题,重奖100分!!考试要用的,非常紧急!!


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


八皇后问题,重奖100分!!考试要用的,非常紧急!!
发表于:2007-06-13 01:41:49 楼主
我编写的八皇后问题,为什么编译时没有错误但执行的时候什么都没得到?(就是只接显示press   any   key   to   continue,按一个任意键就退出了)

#include   <stdio.h>

int   count=0;     //当前正在处理的行

void   solve   (int   (*queen_square)[8]);
void   queen_insert   (int   col,int   (*queen_square)[8]);
void   queen_remove   (int   col,int   (*queen_square)[8]);
void   print   (int   (*queen_square)[8]);
int   is_solved   (int   (*queen_square)[8]);
int   no_queen   (int   col,int   (*queen_square)[8]);

void   main   ()
{
int   queen_square[8][8];     //棋盘数组0表示无皇后,1表示有皇后

for   (int   row=0;row <8;row++)     //初始化
{
for   (int   col=0;col <8;col++)
{
queen_square[row][col]=0;
}
}

solve(queen_square);
}

void   solve   (int   (*queen_square)[8])     //递归函数。返回条件为:找到一个解或者当前行无法放置皇后
{
if   (is_solved(queen_square))     //找到一个解,打印之
{
print(queen_square);
}
else
{
for   (int   col=0;col <8;col++)
{
if   (no_queen(col,queen_square))     //如果这个位置没有被别的皇后所攻击
{
queen_insert(col,queen_square);     //在这里放一个皇后
solve(queen_square);     //继续
queen_remove(col,queen_square);     //递归退出后返回至此
}
}
}
}

void   queen_insert   (int   col,int   (*queen_square)[8])     //在当前位置放一个皇后
{
queen_square[count][col]=1;
++count;
}

void   queen_remove   (int   col,int   (*queen_square)[8])     //移走当前位置的皇后
{
queen_square[count][col]=0;
--count;
}

void   print   (int   (*queen_square)[8])     //打印一个方案
{
for   (int   i=0;i <8;i++)
for   (int   j=0;j <8;j++)
{
if   (queen_square[i][j]==0)
printf( "@ ");
else
printf( "x ");
}
printf( "\n ");
}

int   is_solved   (int   (*queen_square)[8])     //判断是否找到一个方案
{
if   (count==8)
{
return   1;
}
else
return   0;
}

int   no_queen   (int   col,int   (*queen_square)[8])     //判断当前位置是否被别的皇后攻击
{
int   ok=1;
int   i;

for   (i=0;ok   &&   i <count;i++)     //检查当前位置正上方的格子有无皇后
{
if   (queen_square[i][col]==1)
{
ok=0;
}
}
for   (i=1;ok   &&   count-i> =0   &&   col-i> =0;i++)     //检查当前位置左上对角线方向有无皇后
{
if   (queen_square[count-i][col-i]==1)
{
ok=0;
}
}
for   (i=1;ok   &&   count-i> =0   &&   col+i <8;i++)     //检查当前位置右上对角线方向有无皇后
{
if   (queen_square[count-i][col+i]==1)
{
ok=0;
}
}
return   ok;
}
发表于:2007-06-13 07:54:121楼 得分:0
一种比较巧妙的方法:

【很多程序可参考:   http://post.baidu.com/f?kz=8513222】
/*八皇后问题可以有多种解法,我通过找寻棋盘上各个棋子之间的斜率来解决,想与大家共同探讨       -----

set*/

#include   <stdio.h>
#include <math.h>
int   check(int   c[])    
/*判断棋盘上八位数列是否符合斜率不为+1、-1、或0,且每位数字从1到8各出现一次,若符合返回1,否则为

0*/
{
int   n,m;
for   (n=0;n <7;n++)
          for   (m=n+1;m <8;m++)            
              if   (c[m] <1 ¦ ¦c[m]> 8 ¦ ¦c[n]==c[m] ¦ ¦abs(c[n]-c[m])==abs(n-m))
                    return(0);
return(1);
}

int   main()
  {
int   qp[8]={8,7,6,5,4,3,2,1},*p;     /*qp[8]代表棋盘上八行,八个皇后在棋盘上一定是每行一个*/  

 

      /*八个皇后在棋盘上的横坐标一定各不相同,即1---> 8各出现一次*/
      /*由于数12345678可被九整除,于是用穷举法找出所有能被九整除的八位数,*/
      /*其中必包含1---> 8在八位中所有的排列组合*/
      /*检测这些数列就能找出八皇后的所有可能*/

      for   (p=qp;qp[7] <9;qp[0]+=9)
      {
      for   (p=qp;p <&qp[7];)         /*对12345678每次加9,直加到87654321*/
              {
      if   (*p> 9)
                      {
      *(p+1)+=1;
      *p-=10;
      p++;
      }
      else
p+=8;
}
      if   (check(qp))             /*检测八位数列,返回值为真则在屏幕上输出*/
      {
      for   (p=qp;p <=&qp[7];p++)   printf   ( "%d ",*p);
printf   ( "     ");
}    
      }    
return   0;
}
发表于:2007-06-13 08:09:352楼 得分:0
算法的问题,
使用应该是   回溯   ...
发表于:2007-06-13 08:12:503楼 得分:0
#include <stdio.h>
#define   num   8   /*定义数组的大小*/
int   a[num+1];
int   main()
{
int   i,k,flag,not_finish=1,count=0;
i=1;   /*正在处理的元素下标,表示前i-1个元素已符合要求,正在处理第i个元素*/
a[1]=1;   /*为数组的第一个元素赋初值*/
printf( "the   possible   configuration   of   8   queens   are:\n ");
while(not_finish)   /*not_finish=1:处理尚未结束*/
{
while(not_finish&&i <=num)   /*处理尚未结束且还没处理到第num个元素*/
{
for(flag=1,k=1;flag&&k <i;k++)   /*判断是否有多个皇后在同一行*/
if(a[k]==a[i])flag=0;
for(k=1;flag&&k <i;k++)   /*判断是否有多个皇后在同一对角线*/
if((a[i]==a[k]-(k-i)) ¦ ¦(a[i]==a[k]+(k-i)))   flag=0;
if(!flag)   /*若存在矛盾不满足要求,需要重新设置第i个元素*/
{
if(a[i]==a[i-1])   /*若a[i]的值已经经过一圈追上a[i-1]的值*/
{
i--;   /*退回一步,重新试探处理前一个元素*/
if(i> 1&&a[i]==num)
a[i]=1;   /*当a[i]为num时将a[i]的值置1*/
else   if(i==1&&a[i]==num)
not_finish=0;   /*当第一位的值达到num时结束*/
else   a[i]++;   /*将a[i]的值取下一个值*/
}
else   if(a[i]==num)   a[i]=1;
else   a[i]++;   /*将a[i]的值取下一个值*/
}
else   if(++i <=num)
if(a[i-1]==num)   a[i]=1;   /*若前一个元素的值为num则a[i]=1*/
else   a[i]=a[i-1]+1;   /*否则元素的值为前一个元素的下一个值*/
}
if(not_finish)
{
++count;
printf((count-1)%3? "   [%2d]:   ": "   \n[%2d]:   ",count);
for(k=1;k <=num;k++)   /*输出结果*/
printf( "   %d ",a[k]);
if(a[num-1] <num)   a[num-1]++;   /*修改倒数第二位的值*/
else   a[num-1]=1;
i=num-1;   /*开始寻找下一个足条件的解*/
}
}
return   0;
}
发表于:2007-06-13 08:13:564楼 得分:0
在楼主你自己的算法中,
只是递归,
没有使用   回溯的思想,
但是显然直接递归是无法得到解的,
需要回溯求解。
发表于:2007-06-13 08:15:155楼 得分:0
只有调试分析了,分析各个阶段变量的值了。
发表于:2007-06-13 08:35:066楼 得分:0
学习,呵呵
发表于:2007-06-13 09:30:217楼 得分:0
什么是八皇后?
发表于:2007-06-13 09:43:358楼 得分:0
给楼主个代码可以研究一下,这个问题其实不难。就是递归回溯问题。
如果有哪里不理解可以提出。

#include   <iostream>
#include   <stdlib.h>

using   namespace   std;

class   queen{
        friend   int   nqueen(int   );
        private:
                bool   place(int   k);
                void   backtrack(int   t);
                int   n,
                *x;
                long   sum;
        };
       
bool   queen::place(int   k)
{
        for(int   j=1;j <k;j++)
        if((abs(k-j)==abs(x[j]-x[k])) ¦ ¦(x[j]==x[k]))return   false;
        return   true;
        }
       
void   queen::backtrack(int   t)
{
        if(t> n){
                sum++;
                for(int   i=1;i <=n;i++)cout < <x[i] < < "   ";
                cout < <endl;
                }
        else
        for(int   i=1;i <=n;i++){
                x[t]=i;
                if(place(t))backtrack(t+1);
                }
        }
       
int   nqueen(int   n)
{
        queen   x;
        x.n=n;
        x.sum=0;
        int   *p=new   int[n+1];
        for(int   i=0;i <=n;i++)
        p[i]=0;
        x.x=p;
        x.backtrack(1);
        delete   []p;
        return   x.sum;
        }

int   main(int   argc,   char   *argv[])
{
    cout < <nqueen(8);
    system( "pause ");
    return   0;
}
发表于:2007-06-13 09:56:179楼 得分:0
看看这个,   速度相当不错   ...

http://www.jsomers.com/nqueen_demo/nqueens.html
发表于:2007-06-13 10:30:3510楼 得分:0
我的也用了回溯啊

void   solve   (int   (*queen_square)[8])     //递归函数。返回条件为:找到一个解或者当前行无法放置皇后
{
if   (is_solved(queen_square))     //找到一个解,打印之
{
print(queen_square);
}
else
{
for   (int   col=0;col <8;col++)
{
if   (no_queen(col,queen_square))     //如果这个位置没有被别的皇后所攻击
{
queen_insert(col,queen_square);     //在这里放一个皇后
solve(queen_square);     //继续
queen_remove(col,queen_square);     //递归退出后返回至此,这里用了回溯,递归返回时移走前一行的一个皇后,然后继续寻找下一个皇后
}
}
}
}


另一种算法我也知道,用一维数组的,不过我想先用二维来实现一次
发表于:2007-06-13 10:39:2611楼 得分:0
int   iline[9];
void   queen(int   x,int   y);
int   check(int   x,int   y);
int   main()
{
                int   i;
                char                 snumber[256];
                for   (i=1;i <=8;i++)   iline[i]=0;
                for   (i=1;i <=8;i++)
                {
                                queen(i,1);
                }              
}
/*递归调用,在下一行放置皇后*/
void   queen(int   x,int   y)
{
                int   i,j;
                char                 msg[10];
                iline[y]=x;
                if   (y!=8)
                {
                                for(i=1;i <=8;i++)
                                {
                                                if(check(i,y+1)==0)
                                                {
                                                                queen(i,y+1);
                                                }
                                }
                }
                else
                {
                                for(i=1;i <=8;i++)
                                {
                                                sprintf(msg, " ");
                                                for(j=1;j <=8;j++)
                                                {
                                                                if(iline[i]==j)
                                                                {
                                                                                strcat(msg, "后 ");
                                                                }
                                                                else   strcat(msg, "     ");
                                                }
                                                printf(msg);
                                }
                                printf( "\n-------------------------\n ");
                }
}
/*检查之前放下的皇后有无冲突*/
check(int   x,int   y)
{
                int   i;
                for   (i=1;i <y;i++)
                {/*检查正上方和斜线方向*/
                                if((abs(x-iline[i])==(y-i)) ¦ ¦(iline[i]==x))
                                                return   1;
                }
                return   0;
}


很久以前写的
用了一个全局变量
...................................
发表于:2007-06-13 10:42:2412楼 得分:0

                                                printf(msg);
                                                printf( "\n ")/*这里上面忘记加了,原来的程序里面用的是自己的打印函数*/
                                }
                                printf( "\n-------------------------\n ");
发表于:2007-06-13 16:41:1313楼 得分:0
我想要各位看看我的算法有什么问题,而不是给我新的算法……为什么我的算法无法显示结果??
发表于:2007-06-14 20:50:4814楼 得分:0
没人回答……
发表于:2007-06-14 20:56:5915楼 得分:0
什么皇帝这么牛,竟然有八个皇后。
发表于:2007-06-14 21:08:1216楼 得分:0
晕!!!
你的main()函数的返回值为void
最后怎么还能return   ok;?????
发表于:2007-06-15 14:29:4317楼 得分:0
最近我也在看这个问题   下面是我找的资料   不是我写的。。。希望对lz有帮助


八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8x8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

        高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。  

算法一:递归实现n皇后问题

        算法分析:
        数组a、b、c分别用来标记冲突,a数组代表列冲突,从a[0]~a[7]代表第0列到第7列,如果某列上已经有皇后,则为1,否则为0;
        数组b代表主对角线冲突,为b[i-j+7],即从b[0]~b[14],如果某条主对角线上已经有皇后,则为1,否则为0;
        数组c代表从对角线冲突,为c[i+j],即从c[0]~c[14],如果某条从对角线上已经有皇后,则为1,否则为0。

        程序如下:

#i   nclude   <stdio.h>

static   char   queen[8][8];
static   int   a[8];
static   int   b[15];
static   int   c[15];
static   int   iqueennum=0;   //记录总的棋盘状态数

void   qu(int   i);   //参数i代表行

int   main()
{
    int   iline,icolumn;

    //棋盘初始化,空格为*,放置皇后的地方为@
    for(iline=0;iline <8;iline++)
    {
        a[iline]=0;   //列标记初始化,表示无列冲突
        for(icolumn=0;icolumn <8;icolumn++)
            queen[iline][icolumn]= '* ';
    }

    //主、从对角线标记初始化,表示没有冲突
    for(iline=0;iline <15;iline++)
        b[iline]=c[iline]=0;

    qu(0);
    return   0;
}

void   qu(int   i)
{
    int   icolumn;

    for(icolumn=0;icolumn <8;icolumn++)
    {
        if(a[icolumn]==0&&b[i-icolumn+7]==0&&c[i+icolumn]==0)   //如果无冲突
        {
            queen[i][icolumn]= '@ ';   //放皇后
            a[icolumn]=1;   //标记,下一次该列上不能放皇后
            b[i-icolumn+7]=1;   //标记,下一次该主对角线上不能放皇后
            c[i+icolumn]=1;   //标记,下一次该从对角线上不能放皇后
            if(i <7)   qu(i+1);   //如果行还没有遍历完,进入下一行
            else   //否则输出
            {
                //输出棋盘状态
                int   iline,icolumn;
                printf( "第%d种状态为:\n ",++iqueennum);
                for(iline=0;iline <8;iline++)
                {
                    for(icolumn=0;icolumn <8;icolumn++)
                        printf( "%c   ",queen[iline][icolumn]);
                    printf( "\n ");
                }
                printf( "\n\n ");
            }

            //如果前次的皇后放置导致后面的放置无论如何都不能满足要求,则回溯,重置
            queen[i][icolumn]= '* ';
            a[icolumn]=0;
            b[i-icolumn+7]=0;
            c[i+icolumn]=0;
        }
    }
}

算法二:用栈实现的n皇后问题

#i   nclude <iostream.h>
#i   nclude <fstream.h>
/*===定义栈与操作==------------------*/
struct   stack   {
stack   *top;
int   row;
int   col;
}*top;

void   push(int   row,int   col);
void   pop();
/*=====栈的定义完毕==---------------*/

#define   maxqueen   8
/*=======三个冲突数组确定是否能放置皇后
**///0表示无冲突,1表示有冲突
static   int   a[maxqueen];//列冲突
static   int   b[maxqueen*2-1];//主对角线冲突
static   int   c[maxqueen*2-1];//副对角线冲突
static   int   d[maxqueen];
/*======**/

void   setqueen(int   row,int   col);//放置皇后后在该处设置冲突
void   desetqueen(int   row,int   col);
bool   noconflict(int   row,int   col);//判断该位置放置皇后
//是否与其他皇后冲突

//
char   arrayqueen[maxqueen][maxqueen];
ofstream   outqueen;//定义一个输出文件流
void   displayandset();
//
bool   queen();
//
void   main()
{

    top   =   new   stack;
    top-> top=null;

    outqueen.open( "queen.txt ",ios::out,filebuf::openprot);
    for(int   x=0;x <maxqueen;x++)
        for(int   y=0;y <maxqueen;y++)
            arrayqueen[x][y]= '* ';
    cout < < "结果在queen.txt文件中 " < <endl;
    cout < <maxqueen < < "皇后问题是否有解有解?: " < <queen() < <endl;
    outqueen.close();
}
//
bool   queen()
{  
    int   count   =   0;//计数器
    int   col   =   0;//最初从0列开始
    int   precolrow[maxqueen]   =   {0};//记录每一列上次的行数,全部初始化为0
    while(   col <maxqueen   )
    {
        int   row=precolrow[col];//从该列上一次记录的行数开始循环
        while(row <maxqueen)
        {
            if(noconflict(row,col))//判断该位置是否发生冲突
            {
                push(row,col);//将皇后位置压入栈
                setqueen(row,col);//设置该方位有冲突
                if(col==maxqueen-1)//判断是否找到
                {
                    count++;//计数器
                    outqueen < < "第 " < <count < < "种情况: " < <endl;
                    displayandset();   //输出状态,还原空白棋盘
                    desetqueen(row,col);   //将第八个皇后冲突数组置0
                    pop();   //开始寻找下一个状态
                    precolrow[col]=row+1;col--;   //最后一列,row+1行在重新开始寻找
                    break;//跳出行循环,重新开始列循环
                }

                precolrow[col]=row;//记录该列的行
                break;//跳出,进行下一次列循环

            }row++;//如果发生冲突,继续行循环

        }

        if(row <maxqueen)//继续下一列循环
            col++;   //如果row等于了maxqueen,也就是说,该列无法放置皇后,
        else   //需弹出前一列的皇后,
        //而且从前一列再开始循环,并从被弹出的皇后那一行的下一行开始行循环
        {  
            pop();
            precolrow[col]=0;
            --col;
            desetqueen(precolrow[col],col);
            precolrow[col]++;

        }
        if(precolrow[0]==maxqueen&&count> 0)//控制结束
            return   true;
        if(precolrow[0]==maxqueen)
            return   false;

    }
    return   true;
}

void   setqueen(int   row,int   col)
{
    a[col]=1;
    b[row+col]=1;
    c[row-col+maxqueen-1]=1;
    d[row]=1;
}

void   desetqueen(int   row,int   col)
{
    a[col]=0;
    b[row+col]=0;
    c[row-col+maxqueen-1]=0;
    d[row]=0;
}


bool   noconflict(int   row,int   col)
{
    if(a[col]!=1&&b[row+col]!=1&&c[row-col+maxqueen-1]!=1&&d[row]!=1)
        return   true;
    return   false;
}

void   displayandset()
{
    stack   *temp=top-> top;
    for(int   x=0;x <maxqueen;x++,temp=temp-> top)
        arrayqueen[temp-> row][temp-> col]= '@ ';
    for(   x=0;x <maxqueen;x++)
    {   for(int   y=0;y <maxqueen;y++)
            outqueen < <arrayqueen[x][y] < < '   ';
        outqueen < < '\n ';
    }
    temp=top-> top;
    for(x=0;x <maxqueen;x++,temp=temp-> top)
        arrayqueen[temp-> row][temp-> col]= '* ';
}


void   push(int   row,int   col)
{
    stack   *s   =   new   stack;
    s-> row   =   row;
    s-> col   =   col;
    s-> top   =   top-> top;
    top-> top   =   s;

}


void   pop()
{
    if(top-> top!=null)
    {
        stack   *temp=top-> top;
        top-> top   =   temp-> top;
        delete   temp;
    }
}

输出结果有92种状态
发表于:2007-06-16 09:25:4018楼 得分:0
c/c++语言经典实用趣味程序设计编程百例精解(10)
(详解收藏在)http://www.klfd.net.cn/?p=393
91.人机猜数游戏      
92.人机猜数游戏(2)    
93.汉诺塔  
94.兎子产子  
95.将阿拉伯数字转换为罗马数字  
96.选美比赛  
97.满足特异条件的数列      
-> 98.八皇后问题  
99.超长正整数的加法    
100.数字移动
http://www.klfd.net.cn/?p=393
有详解
发表于:2007-06-16 17:33:3219楼 得分:0
都是高手。。哎我都看不懂
发表于:2007-06-18 15:43:4420楼 得分:0
google之。
发表于:2007-06-18 21:21:5021楼 得分:0
#include <iostream>
#include   <stdlib.h>
using   namespace   std;

int   a[8];
void   display()
{   static   int   count=0;
          int   i,j;
          cout < < "no. " < <++count < < ":   " < <endl;
          for   (i=0;i <8;i++)
          {   for   (j=0;j <8;j++)
                          if   (a[i]==j)
                                  cout < < "q   ";
                          else
                                  cout < < "*   ";
                  cout < <endl;   }}
int   check_list(int   i,int   r)
{int   j;
        for   (j=0;j <i;j++)
              {if   (a[j]==r   ¦ ¦   a[j]+j==i+r   ¦ ¦   a[j]-j==r-i)
                      return   0;}                     return   1;}
void   playwork(int   i)
{   int   r;
          if   (i==8)   display();
          else
          for   (r=0;r <8;r++)
          if   (check_list(i,r))
          {   a[i]=r;
                  playwork(i+1);   }   }
int   main()
{playwork(0);
        cout < < '\n ' < < "##   voer   ## " < <endl;
return   0;}
发表于:2007-06-18 21:42:5622楼 得分:0
跑的最慢的   ....

#include   <stdio.h>
#include   <string.h>

#define     n (10)
#define     o(o) f[j]   o   f[n+i+j]   o   f[4*n+i-j]

int   f[   5   *   n   ];
void   slove(   int   i   ,   int   j   )
{
for(j=1;j <=n;++j)   i> n?printf( "%c%-2d ",j==1?(++f[0], '\n '): '   ',f[j]):!(o( ¦))?(o(=)=i,slove(i+1,0),o(=)=0):0;
}
int   main()
{
slove(1,0);
printf(   "\ncount==%d\n "   ,   f[0]   );
return   0;
}

发表于:2007-06-19 15:15:0723楼 得分:0
又见八皇后!
发表于:2007-06-19 17:38:2024楼 得分:0
小弟今天今天第一次看见这个问题,研究了一下。8*8的太大,我分析了下4*4的情况和5*5的情况,发现一个有趣的问题,皇后在棋盘上的位置正好是一个马走的规则,也就是一个日字。不知道是不是8*8也是这样。4*4的只有2种,5*5的有10种,每种情况都可以用一个马从一个点跳到另一个点,而且不重复。
发表于:2007-06-19 18:14:1625楼 得分:0
mark
发表于:2007-06-28 17:33:5026楼 得分:0
看上面的程序都好长啊!我们老师有一个较简单的方法,在这介绍给你,可能迟了,不过学点还是好的.
#include   "stdio.h "
#include   "math.h "
int   row[8];           //数组row[1]~row[8]存储第一列至第八列皇后的行号n1,n2,...,n8
void   arrange(int   k)       //安排第k列至第八列皇后
{   int   i,j;
    if(k> 8)
            {for(i=1;i <=8;i++)printf( "%2d ",row[i]);  //k> 8则应该输出各列皇后的行号
                printf( "\n ");return;
              }
      for(j=1;j <=8;j++)   //试探第k列的每一个行号
      {   for(i=1;i <k;i++)if(row[i]==j ¦ ¦(k-i)==abs(row[i]-j))break;
          if(i> =k){row[k]=j;     //i> =k说明第k列的第j行可用,则放置一个皇后
                            arrange(k+1);   //安排第k+1列至第8列皇后
                            }
        }
}
void   main()
{
    arrange(1);
}
发表于:2007-06-28 18:15:2327楼 得分:0
编译没问题,运行出错,那太正常了,逻辑错误是编译器检查不出来的,不过以前自己写了个8皇后的程序,可以看一下.

#include   <iostream>
#include   <cstdio>
#include   <ctime>
#include   <cmath>

using   namespace   std;

void   queen(int**   array,   int   row,   file*   fp);
bool   isavailable(int**   array,   int   y,   int   x);
bool   isresult(int**   array);

int   main(int   arg,   char**   argv)   {
                int**   array;
               
                //   分配空间
                array   =   new   int*[8];
                for   (int   i   =   0;   i   <   8;   i++)   {
                                array[i]   =   new   int[8];
                }
               
                //   初始化皇后
                for   (int   i   =   0;   i   <   8;   i++)   {
                                for   (int   j   =   0;   j   <   8;   j++)   {
                                                array[i][j]   =   0;
                                }
                }
               
                file*   fp   =   fopen( "data.txt ",   "w ");
                queen(array,   0,   fp);
                fclose(fp);
               
                //   释放空间
                for   (int   i   =   0;   i   <   8;   i++)   {
                                delete[]   array[i];
                }
                delete   array;
                array   =   null;

                return   0;
}

void   queen(int**   array,   int   row,   file*   fp)   {
                static   int   size   =   0;
                if   (row   >   7)   {
                                return;
                }

                //int   i   =   row;
                for   (int   j   =   0;   j   <   8;   j++)   {
                                //   如果合法
                                if   (isavailable(array,   row,   j))   {
                                                array[row][j]   =   1;
                                               
                                                //   当前位置合法,赋值后,进入下一行
                                                queen(array,   row   +   1,   fp);

                                                //   如果退回来后不是结果,则把刚设置的当前位置重新赋值为0
                                                //   是结果,则打印出来
                                                if   (isresult(array))   {
                                                                //   把结果写入文件
                                                                fputc( '\n ',   fp);
                                                                fputs( "*********************************** ",   fp);
                                                                fprintf(fp,   "   %d   ",   size++);
                                                                fputs( "*********************************** ",   fp);
                                                                fputc( '\n ',   fp);
                                                                for   (int   m   =   0;   m   <   8;   m++)   {
                                                                                for   (int   n   =   0;   n   <   8;   n++)   {
                                                                                                if   (array[m][n]   ==   1)   {
                                                                                                                fputc( '# ',   fp);
                                                                                                                fputc( '   ',   fp);
                                                                                                                fputc( '   ',   fp);
                                                                                                }   else   {
                                                                                                                fputc( 'o ',   fp);
                                                                                                                fputc( '   ',   fp);
                                                                                                                fputc( '   ',   fp);
                                                                                                }
                                                                                }
                                                                                fputc( '\n ',   fp);  
                                                                }

                                                }
                                                array[row][j]   =   0;

                                }
                }
}

bool   isavailable(int**   array,   int   row,   int   column)   {   //   第y行,x列
                int   i,   j;

                //   检查y行
                for   (i   =   0;   i   <   8;   i++)   {
                                if   (array[row][i]   !=   0)   {
                                                return   false;
                                }
                }

                //   检查x列
                for   (j   =   0;   j   <   8;   j++)   {
                                if   (array[j][column]   !=   0)   {
                                                return   false;
                                }
                }

                //   检查对角向左上
                i   =   row;
                j   =   column;
                while   (i   > =   0   &&   j   > =   0)   {
                                if   (array[i][j]   !=   0)   {
                                                return   false;
                                }
                                i--;
                                j--;
                }

                //   检查对角向右上
                i   =   row;
                j   =   column;
                while   (i   > =   0   &&   j   <   8)   {
                                if   (array[i][j]   !=   0)   {
                                                return   false;
                                }
                                i--;
                                j++;
                }

                //   检查对角向左下
                i   =   row;
                j   =   column;
                while   (i   <   8   &&   j   > =   0)   {
                                if   (array[i][j]   !=   0)   {
                                                return   false;
                                }
                                i++;
                                j--;
                }

                //   检查对角向右下
                i   =   row;
                j   =   column;
                while   (i   <   8   &&   j   <   8)   {
                                if   (array[i][j]   !=   0)   {
                                                return   false;
                                }
                                i++;
                                j++;
                }

                return   true;
}

bool   isresult(int**   array)   {
                int   size   =   0;   //   皇后个数

                //   统计皇后个数
                for   (int   i   =   0;   i   <   8;   i++)   {
                                for   (int   j   =   0;   j   <   8;   j++)   {
                                                if   (array[i][j]   !=   0)   {
                                                                size++;
                                                }
                                }
                }

                //   没有8个皇后,说明不是结果
                if   (size   !=   8)   {
                                return   false;
                }

                return   true;
}

发表于:2007-06-28 18:29:0828楼 得分:0
gdckwxiao_swjtu()   (   一级(初级))   信誉:100   2007-6-28   17:33:50   得分:0

看上面的程序都好长啊!我们老师有一个较简单的方法,在这介绍给你,可能迟了,不过学点还是好的.
#include   "stdio.h "
#include   "math.h "
int   row[8];   //数组row[1]~row[8]存储第一列至第八列皇后的行号n1,n2,...,n8
void   arrange(int   k)   //安排第k列至第八列皇后
{   int   i,j;
if(k> 8)
{for(i=1;i <=8;i++)printf( "%2d ",row[i]);  //k> 8则应该输出各列皇后的行号
printf( "\n ");return;
}
for(j=1;j <=8;j++)   //试探第k列的每一个行号
{   for(i=1;i <k;i++)if(row[i]==j ¦ ¦(k-i)==abs(row[i]-j))break;
if(i> =k){row[k]=j;   //i> =k说明第k列的第j行可用,则放置一个皇后
arrange(k+1);   //安排第k+1列至第8列皇后
}
}
}
void   main()
{
arrange(1);
}

------------------------------------------------------------------
这个太牛x了
发表于:2007-06-28 18:45:1629楼 得分:0
&_&
发表于:2007-06-29 01:56:5930楼 得分:0
给大家分享一个一行解决问题的八皇后代码:
#include   <stdio.h>
#define   q(o)   a[j]o[j+i+7]o[j-i+31]
int   a[39];
void   main(int   i,int   j)
{
  bool   fk=false;
  static   num=0;
  for(j=9;--j;i> 8?fk=true,printf( "%2d   ",a[j]):q( ¦a) ¦ ¦(q(=a)=i,main(i+1,j),q(=a)=0));
  if(fk)   printf( "\t%d\n ",++num);
}
输出每一行八个数字,代表每个皇后在那一行的位置.
发表于:2007-06-29 09:32:2131楼 得分:0
mark
发表于:2007-06-29 09:52:1432楼 得分:0
coldwindtang(风)  
的代码太有创意了
发表于:2007-06-29 15:35:2733楼 得分:0
我记得好象有一本数据结构是清华出的影印版,上面有详细解释,不过作者我忘了啊


快速检索

最新资讯