鱼C论坛

 找回密码
 立即注册
查看: 10208|回复: 18

[技术交流] 八皇后问题(递归求解)

[复制链接]
发表于 2013-3-2 03:00:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题(这节课小甲鱼先用递归算法来解)。

该问题是十九世纪著名的数学家高斯1850年提出:

在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

高斯先生当年由于没有学好计算机编程,没日没夜地计算呀,得出结论是76种,硬生生把自己给“搞死”了!

对了,当年还没有计算机……


视频讲解:http://blog.fishc.com/2228.html

源代码参考:http://bbs.fishc.com/thread-28183-1-1.html
小甲鱼最新课程 -> https://ilovefishc.com
发表于 2013-3-9 07:01:46 | 显示全部楼层
下载看看 虽然目前对递归还不怎么了解
小甲鱼最新课程 -> https://ilovefishc.com
发表于 2013-7-12 10:28:59 | 显示全部楼层
Dim a(8, 8)
For i = 0 To 7
    For j = 0 To 7
        a(i, j) = 0
    Next
Next
num=1
For n0 = 0 To 7
    a(0, n0) = 1
    hang0=n0
    For n1 = 0 To 7
        If safe(1, n1) = 1 Then
            a(1, n1) = 1
            hang1=n1
            For n2 = 0 To 7
                If safe(2, n2) = 1 Then
                    a(2, n2) = 1
                    hang2=n2
                    For n3 = 0 To 7
                        If safe(3, n3) = 1 Then
                            a(3, n3) = 1
                            hang3=n3
                            For n4 = 0 To 7
                                If safe(4, n4) = 1 Then
                                    a(4, n4) = 1
                                    hang4=n4
                                    For n5 = 0 To 7
                                        If safe(5, n5) = 1 Then
                                            a(5, n5) = 1
                                            hang5=n5
                                            For n6 = 0 To 7
                                                If safe(6, n6) = 1 Then
                                                    a(6, n6) = 1
                                                    hang6=n6
                                                    For n7 = 0 To 7
                                                        If safe(7, n7) = 1 Then
                                                            a(7, n7) = 1
                                                            hang7=n7
                                                            Call printf()
                                                            num=num+1
                                                        End If
                                                    Next
                                                    a(7, hang7) = 0
                                                End If
                                                a(6, hang6) = 0
                                            Next
                                        End If
                                        a(5, hang5) = 0
                                    Next
                                End If
                                a(4, hang4) = 0
                            Next
                        End If
                        a(3, hang3) = 0
                    Next
                End If
                a(2, hang2) = 0
            Next
        End If
        a(1, hang1) = 0
    Next
    a(0, hang0) = 0
Next
Sub printf()
    p=""
    For i = 0 To 7
        For j = 0 To 7
            P = P & CStr(a(i, j)) & " "
        Next
        P = P & vbCrLf
    Next
    MsgBox p, vbokonly, "第" & num & "种皇后位置!"
End Sub
Function safe(x, y)
    For h= 0 To 7
        For l = 0 To 7
            If a(h, l) = 1 Then
                If (h = x) or (l=y) or ((h - l)= (x - y)) or ((h + l) = (x + y)) Then
                    safe = 0
                    Exit Function
                Else
                    safe = 1
                End If        
            End If       
        Next
    Next
End Function
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2013-8-7 19:27:27 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-18 11:05:59 | 显示全部楼层
强烈支持楼主ing……
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-22 13:10:51 | 显示全部楼层
看我同学写的八皇后,多么雷人。。。
  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. int pd(int i,int h[30][30],int j)
  5. {
  6.         int t;
  7.         t=h[i][j]*h[i][j+1]*h[i][j+2]*h[i][j+3]*h[i][j+4]*h[i][j+5]*h[i][j+6]*h[i][j+7]*h[i][j+8];//列
  8.         t=t*h[i][j-1]*h[i][j-2]*h[i][j-3]*h[i][j-4]*h[i][j-5]*h[i][j-6]*h[i][j-7]*h[i][j-8];//列
  9.         t=t*h[i+1][j]*h[i+2][j]*h[i+3][j]*h[i+4][j]*h[i+5][j]*h[i+6][j]*h[i+7][j]*h[i+8][j];//行
  10.         t=t*h[i-1][j]*h[i-2][j]*h[i-3][j]*h[i-4][j]*h[i-5][j]*h[i-6][j]*h[i-7][j]*h[i-8][j];//行
  11.         t=t*h[i+1][j+1]*h[i+2][j+2]*h[i+3][j+3]*h[i+4][j+4]*h[i+5][j+5]*h[i+6][j+6]*h[i+7][j+7]*h[i+8][j+8];//xie
  12.         t=t*h[i-1][j+1]*h[i-2][j+2]*h[i-3][j+3]*h[i-4][j+4]*h[i-5][j+5]*h[i-6][j+6]*h[i-7][j+7]*h[i-8][j+8];//xie
  13.         t=t*h[i+1][j-1]*h[i+2][j-2]*h[i+3][j-3]*h[i+4][j-4]*h[i+5][j-5]*h[i+6][j-6]*h[i+7][j-7]*h[i+8][j-8];//xie
  14.         t=t*h[i-1][j-1]*h[i-2][j-2]*h[i-3][j-3]*h[i-4][j-4]*h[i-5][j-5]*h[i-6][j-6]*h[i-7][j-7]*h[i-8][j-8];//xie

  15.         return t;
  16. }
  17. int main()
  18. {
  19.         int h[30][30];
  20.         for (int qqq=0;qqq<30;qqq++)
  21.         {
  22.                 for(int qq=0;qq<30;qq++)
  23.                 {
  24.                         h[qqq][qq]=1;
  25.                 }
  26.         }
  27.         int n,m,k;
  28.         int y,e,sa,si,w,l,q,b,sum;
  29.         sum=0;
  30.         for (y=11;y<=18;y++)
  31.         {               
  32.                 h[11][y]=0;//11
  33.                 for (e=11;e<=18;e++)
  34.                 {
  35.                         if(pd(12,h,e)==0)//12
  36.                         {                               
  37.                         }
  38.                         else
  39.                         {
  40.                                 h[12][e]=0;
  41.                                
  42.                                 for(sa=11;sa<=18;sa++)//13
  43.                                 {
  44.                                         if(pd(13,h,sa)==0)
  45.                                         {                                               
  46.                                         }
  47.                                         else
  48.                                         {
  49.                                                 h[13][sa]=0;
  50.                                                
  51.                                                 for (si=11;si<=18;si++)//14
  52.                                                 {
  53.                                                         if(pd(14,h,si)==0)
  54.                                                         {                                                               
  55.                                                         }
  56.                                                         else
  57.                                                         {
  58.                                                                 h[14][si]=0;
  59.                                                        
  60.                                                                 for(w=11;w<19;w++)//15
  61.                                                                 {
  62.                                                                         if(pd(15,h,w)==0)
  63.                                                                         {                                                                               
  64.                                                                         }
  65.                                                                         else
  66.                                                                         {
  67.                                                                                 h[15][w]=0;
  68.                                                                                
  69.                                                                                 for (l=11;l<=18;l++)//16
  70.                                                                                 {
  71.                                                                                         if(pd(16,h,l)==0)
  72.                                                                                         {                                                                                               
  73.                                                                                         }
  74.                                                                                         else
  75.                                                                                         {                       
  76.                                                                                                
  77.                                                                                                 h[16][l]=0;
  78.                                                                                                
  79.                                                                                                 for (q=11;q<=18;q++)//17
  80.                                                                                                 {
  81.                                                                                                         if(pd(17,h,q)==0)
  82.                                                                                                         {                                                                                                               
  83.                                                                                                         }
  84.                                                                                                         else
  85.                                                                                                         {                                                                                                               
  86.                                                                                                                 h[17][q]=0;                                                                                                       
  87.                                                                                                                 for (b=11;b<=18;b++)//18
  88.                                                                                                                 {

  89.                                                                                                                         if(pd(18,h,b)==0)
  90.                                                                                                                         {                                                                                                                               
  91.                                                                                                                         }
  92.                                                                                                                         else
  93.                                                                                                                         {                                                                                                                               
  94.                                                                                                                                 sum++;
  95.                                                                                                                                 h[18][b]=0;
  96.                                                                                                                                 for (k=11;k<19;k++)
  97.                                                                                                                                 {
  98.                                                                                                                                         cout<<h[11][k];
  99.                                                                                                                                 }
  100.                                                                                                                                 cout<<endl;
  101.                                                                                                                                 for (k=11;k<19;k++)
  102.                                                                                                                                 {
  103.                                                                                                                                         cout<<h[12][k];
  104.                                                                                                                                 }
  105.                                                                                                                                 cout<<endl;
  106.                                                                                                                                 for (k=11;k<19;k++)
  107.                                                                                                                                 {
  108.                                                                                                                                         cout<<h[13][k];
  109.                                                                                                                                 }
  110.                                                                                                                                 cout<<endl;
  111.                                                                                                                                 for (k=11;k<19;k++)
  112.                                                                                                                                 {
  113.                                                                                                                                         cout<<h[14][k];
  114.                                                                                                                                 }
  115.                                                                                                                                 cout<<endl;
  116.                                                                                                                                 for (k=11;k<19;k++)
  117.                                                                                                                                 {
  118.                                                                                                                                         cout<<h[15][k];
  119.                                                                                                                                 }
  120.                                                                                                                                 cout<<endl;
  121.                                                                                                                                 for (k=11;k<19;k++)
  122.                                                                                                                                 {
  123.                                                                                                                                         cout<<h[16][k];
  124.                                                                                                                                 }
  125.                                                                                                                                 cout<<endl;
  126.                                                                                                                                 for (k=11;k<19;k++)
  127.                                                                                                                                 {
  128.                                                                                                                                         cout<<h[17][k];
  129.                                                                                                                                 }
  130.                                                                                                                                 cout<<endl;
  131.                                                                                                                                 for (k=11;k<19;k++)
  132.                                                                                                                                 {
  133.                                                                                                                                         cout<<h[18][k];
  134.                                                                                                                                 }
  135.                                                                                                                                 cout<<endl;
  136.                                                                                                                                 cout<<"  "<<endl;
  137.                                                                                                                                 cout<<"  "<<endl;
  138.                                                                                                                                 cout<<"  "<<endl;                                                                                                                                                       
  139.                                                                                                                         }
  140.                                                                                                                 }
  141.                                                                                                                 for (n=18;n<30;n++)
  142.                                                                                                                 {
  143.                                                                                                                         for(m=0;m<30;m++)
  144.                                                                                                                         {
  145.                                                                                                                                 h[n][m]=1;
  146.                                                                                                                         }
  147.                                                                                                                 }
  148.                                                                                                                 h[17][q]=1;
  149.                                                                                                         }
  150.                                                                                                 }
  151.                                                                                                 h[16][l]=1;
  152.                                                                                                 for (n=17;n<30;n++)
  153.                                                                                                 {
  154.                                                                                                         for(m=0;m<30;m++)
  155.                                                                                                         {
  156.                                                                                                                 h[n][m]=1;
  157.                                                                                                         }
  158.                                                                                                 }
  159.                                                                                         }
  160.                                                                                 }
  161.                                                                                 h[15][w]=1;
  162.                                                                                 for (n=16;n<30;n++)
  163.                                                                                 {
  164.                                                                                         for(m=0;m<30;m++)
  165.                                                                                         {
  166.                                                                                                 h[n][m]=1;
  167.                                                                                         }
  168.                                                                                 }
  169.                                                                         }
  170.                                                                 }
  171.                                                                 h[14][si]=1;
  172.                                                                 for (n=15;n<30;n++)
  173.                                                                 {
  174.                                                                         for(m=0;m<30;m++)
  175.                                                                         {
  176.                                                                                 h[n][m]=1;
  177.                                                                         }
  178.                                                                 }
  179.                                                         }
  180.                                                 }
  181.                                                 h[13][sa]=1;
  182.                                                 for (n=14;n<30;n++)
  183.                                                 {
  184.                                                         for(m=0;m<30;m++)
  185.                                                         {
  186.                                                                 h[n][m]=1;
  187.                                                         }
  188.                                                 }
  189.                                         }                               
  190.                                 }

  191.                                 h[12][e]=1;
  192.                                 for (n=13;n<25;n++)
  193.                                 {
  194.                                         for(m=0;m<30;m++)
  195.                                         {
  196.                                                 h[n][m]=1;
  197.                                         }
  198.                                 }
  199.                         }
  200.                 }
  201.                 for (n=12;n<30;n++)
  202.                 {
  203.                         for(m=0;m<30;m++)
  204.                         {
  205.                                 h[n][m]=1;
  206.                         }
  207.                 }
  208.                 h[11][y]=1;
  209.         }
  210.         cout<<sum<<endl;
  211.         return 0;
  212. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-2-22 16:45:48 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-4-17 17:47:24 | 显示全部楼层
请求楼主帮忙
我的问题:八皇后我的理解是把所有结果遍历一遍  楼主的代码从1——7行都有  for(i=0;i<8;++i){EightQuee}
的遍历   为什么第一行只遍历了一次  为什么结果不是8*92   
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-5-4 20:07:53 | 显示全部楼层
强烈支持楼主ing……
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-10-23 17:39:45 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2014-10-23 17:47:41 | 显示全部楼层
{:1_1:}
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2014-12-1 21:58:23 | 显示全部楼层
andalousie 发表于 2014-2-22 13:10
看我同学写的八皇后,多么雷人。。。

神人也~~~受我膜拜~~~~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-1-15 11:36:29 | 显示全部楼层
真是难得给力的帖子啊。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-7-14 17:06:25 | 显示全部楼层
八皇后
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<conio.h>
#define N 8 //皇后数=棋盘行列数
int a[N]; //a[i]为第i行皇后所在列
void show() //图形化输出
{
    int i;
    int p,q ;
    int b[N][N]={0};
    static int t=1;
    printf("第%d个解为: ",t++);
    for(i=0;i<N;i++)
    {
        b[i][a[i]]=1;
        printf("(%d,%d) ",i,a[i]);
    }
    printf("\n");
    for(p=0;p<N;p++)
    {
        for(q=0;q<N;q++)
        {
            if(b[p][q]==1)
                printf("●");
            else
                printf("○");
        }
        printf("\n");
    }
}
int check(int n) //满足条件返回1,否则返回0
{
    int i;
    for(i=0;i<n;i++)
    {
        if(a[i]==a[n]||fabs(n-i)==fabs(a[i]-a[n])) //at the same column or diagonal (对角线)
            return 0;
    }
    return 1;
}
void put(int n) //在第n行放置第n个皇后
{
    int i;
    if(n==N)
        return ;
    for(i=0;i<N;i++)
    {
        a[n]=i;
        if(check(n)) //位置合法
        {
            if(n==N-1) //皇后全部放置完毕
                show();
            else
                put(n+1);
        }
    }
}
int main ()
{
    put(0);
    return 0;
}
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-18 19:37:44 | 显示全部楼层
5L超神了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-25 15:06:09 | 显示全部楼层

下载看看 虽然目前对递归还不怎么了解
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-3-1 12:24:15 | 显示全部楼层
先看
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-11-21 23:31:39 | 显示全部楼层
  1. #include<stdio.h>
  2. #define N 8
  3. int count=0;

  4. int IsSafe(int row,int n,int (*chess)[N])
  5. {
  6.         //判断列,斜向是否有冲突
  7.         //情况分为5种,左上,左下,右上,右下,本列
  8.         int i,j;
  9.         int flag;
  10.         flag=1;//安全
  11.         for(i=0;i<N;i++) //本列
  12.         {
  13.                 if( 1 == chess[i][n])
  14.                 {
  15.                         flag=0;
  16.                         break;
  17.                 }
  18.         }
  19.         for(i=row,j=n;i>=0&&j>=0;--i,--j)//左上
  20.         {
  21.                 if( 1 == chess[i][j])
  22.                 {
  23.                         flag=0;
  24.                         break;               
  25.                 }
  26.         }
  27.         for(i=row,j=n;i<N&&j>=0;++i,--j)//左下
  28.         {
  29.                 if( 1 == chess[i][j])
  30.                 {
  31.                         flag=0;
  32.                         break;               
  33.                 }
  34.         }
  35.         for(i=row,j=n;i>=0&&j<N;--i,++j)//右上
  36.         {
  37.                 if( 1 == chess[i][j])
  38.                 {
  39.                         flag=0;
  40.                         break;               
  41.                 }
  42.         }
  43.         for(i=row,j=n;i<N&&j<N;++i,++j)//右下
  44.         {
  45.                 if( 1 == chess[i][j])
  46.                 {
  47.                         flag=0;
  48.                         break;               
  49.                 }
  50.         }
  51.         return flag;
  52. }
  53. // 参数row: 表示起始行
  54. // 参数n: 表示列数
  55. // 参数(*chess)[N]: 表示指向棋盘每一行的指针
  56. void EightQueen(int row,int n,int (*chess)[N])//重点
  57. {
  58.         //操作下标为 row 的那行
  59.         //复制整个棋盘
  60.         int chess2[N][N]={0};
  61.         int i,j;
  62.         for(i=0;i<N;++i)//复制,形成副本,然后操作副本
  63.         {
  64.                 for(j=0;j<N;++j)
  65.                         chess2[i][j]=chess[i][j];
  66.         }
  67.         //判断row==N,row==N代表溢出了,如果溢出了,就输出这种可能
  68.         //否则,继续填棋
  69.         if( N==row )//棋盘满了,输出副本
  70.         {
  71.                 for(i=0;i<N;++i)
  72.                 {
  73.                         for(j=0;j<N;++j)
  74.                                 printf("%d ",chess2[i][j]);
  75.                         printf("\n");
  76.                 }
  77.                 printf("\n\n");
  78.                 count++;        //出现一种可能               
  79.         }
  80.         else        //无溢出,棋盘未满,继续填棋
  81.         {
  82.                 for(j=0;j<N;++j)//填充本行 的0到N-1列
  83.                 {
  84.                         if(IsSafe(row,j,chess2))//1:安全,row行j列填棋
  85.                         {
  86.                                 for(i=0;i<N;++i)
  87.                                         chess2[row][i]=0;//为了数据安全,清空本行
  88.                                 chess2[row][j]=1;//row行j列填棋
  89.                                 EightQueen(row+1,n,chess2);//填充下一行
  90.                         }
  91.                 }
  92.         }
  93. }
  94. //*(*(chess+i)+j)    (*chess)[N]
  95. int main(int argc, char *argv[]) {
  96.         //主函数说明:
  97.         int chess[N][N]={0};
  98.         EightQueen(0,N,chess);
  99.         printf("%d皇后有%d种可能!\n\n",N,count);
  100.         return 0;
  101. }
复制代码


本人的拙见
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2019-11-21 23:34:13 | 显示全部楼层

可以试试从列开始放皇后
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-13 14:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表