八皇后问题用C语言解决

TO live is the rarest thing in the world.Most people exist.That is all.

生活,世间最罕见之事。生存,世间最常见之事。仅此而已。

=========================================================================

今天刷题时遇到一个问题

在8X8的国际象棋上摆放8个皇后,使其不能相会攻击,即任意两个格子不得处在同一行、同一列或者同一对角线上,请问总共有多少种符合条件的摆法?

由于8个皇后的任意两个不能处在同一行,那么肯定是每一个皇后占据一行。于是我们可以定义一个数组queens[8],数组中第i个数字表示位于第i行的皇后的列号。先把数组的8个数字分别用0~7初始化,接下来就是对数组做全排列。因为我们是用不同的数字初始化数组,所以任意两个皇后肯定不同列。还需排队每一个排列对应的8个皇后是不是在同一对角线上,也就是对于数组的两个下标和k,是不是i-k=queens[i]-queens[k]或者k-i=queens[i]-queens[k].

--来自《剑指offer》

代码我就没有一个个敲了,直接在作业帮拷贝了一份,亲测有效,我稍微改了一点点,写这个的老铁挺用心的,还把每一种情况列出来了。

#include<stdio.h>
#include<math.h>
#include<stdlib.h>

int c = 0;//统计八皇后摆放总数
int i = 0;//统计比较次数
void PrintTheChessBoard(int queens[], int n)//打印棋盘
{
    int i, j;//控制循环
    printf("NO. %d method.\n",c); //输出第num种摆法
    for (i = 0; i < n; i ++)//控制循环
    {
      for (j = 0; j < queens[i]; j ++)
        {
         printf(" *");//打印*
        }
      printf(" Q");//打印皇后
      for (j = n-1; j > queens[i]; j --)
        {
         printf(" *");//打印*
        };
      putchar('\n');//换行
    }
}

int CheckTheChessBoard(int queens[], int i)// 检查棋盘从第 0 行到第 i 行的布局是否合法。
{
  int j, k;
  for (j = 0; j <= i; j ++)//循环控制
    { 
     for (k = 0; k <= i; k ++)//循环控制
       {
         if (j != k && (queens[j] == queens[k]||abs(queens[j] - queens[k]) == abs(j - k))) 
         //j!=k判断是否在同一行
	     //queens[j] == queens[k]是否在同一列上 ,因为每一列都用了不同数字表示
	     //abs(queens[j] - queens[k]) == abs(j - k)判断是否在对角线上,abs函数求表达式绝对值
          {
           return 0;//若在同一行,同一列或者同一对角线上,返回0
          }
        }
    }
    return 1;//若不在同一行,同一列或者同一对角线上,返回1
}

void Trial(int queens[], int i, int n)//当判断八行皇后摆法格局都合法,则调用打印函数
{
   if (i >= n)//当判断皇后摆法都合法时,打印棋盘
     {
      c ++;
      PrintTheChessBoard(queens, n);//调用PrintTheChessBoard()函数,打印皇后
     }
   else
     {
       int j;
       for (j = 0; j < n; j ++)
       {
        queens[i] = j;//对queen数组从新赋值
        if(CheckTheChessBoard(queens, i))//调用CheckTheChessBoard函数,若返回数为1,就再次调用Trial函数
         {
          Trial(queens, i + 1, n);
         }
       }
     }
}

void main()
{ 
printf("The Queen number is Eight \n\n");//定义问题是八皇后
int queens[] = {0};//给queen数组赋初值
Trial(queens, 0, 8);//调用Trial函数
printf("There is %d answers for the 8 Queen question\n\n",c);
getchar();//从键盘获取字符
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值