Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2856981
  • 博文数量: 471
  • 博客积分: 7081
  • 博客等级: 少将
  • 技术积分: 5369
  • 用 户 组: 普通用户
  • 注册时间: 2012-01-04 21:55
文章分类

全部博文(471)

文章存档

2014年(90)

2013年(69)

2012年(312)

分类: C/C++

2012-04-16 16:08:13

hdu 2553 N皇后问题 原题链接  

   今下午看了一下八皇后问题,所以强烈的想AC一道题。。hdu上的此题 刚刚好。哈哈。

       题目大意:在一个n*n的棋盘上放置n个皇后棋子。皇后可以向行,列,对角线攻击。求皇后互不攻击的摆法有多少种。

     回溯法以前看到过名称 ,但不懂具体怎么用。 今天终于是理解一点了。回溯法的精华就是边生成边检验,所以减少了很多不必要的枚举。 具体的思路会在代码中有注释。

     这道题最直接的思路就是枚举 暴力解决,但是显然是不行的。

      所以只能用回溯。 基本思路 ,一行一行的放 皇后, 然后再递归判断是否与之前已放好的皇后有冲突,一旦有冲突,则不需要继续下一行的搜索,直接返回(省去不必要的枚举)。

       另外关于这题,还有一点,我第一次交的时候TLE了,说明测试数据特别多。所以得先预处理(这个亏吃了很多次了,牢记牢记).

在循环中递归

row

line[row]=i,(i=0,1,2,...,n)

j

 


 

点击(此处)折叠或打开

  1. //八皇后问题 回溯法
  2. #include<stdio.h>
  3. int tot=0,row,line[10],n;
  4. int main()
  5. {
  6.     void search(int );
  7.     int a[11];
  8.     for(n=1;n<=10;n++) //之前就是没有这一步预处理,所以TLE了 TT
  9.     {
  10.         tot=0;
  11.         search(0);
  12.         a[n]=tot;
  13.     }
  14.     while(scanf("%d",&n)!=EOF&&n)
  15.          printf("%d\n",a[n]);
  16.     return 0;
  17. }
  18. void search(int row) //递归搜索可行解
  19. {
  20.     int i,j;
  21.      if(row==n) tot++; //当row=n时,说明每一行的皇后都不冲突,即为可行解
  22.      else
  23.      for(i=0;i<n;i++)
  24.      {
  25.          int ok=1;
  26.          line[row]=i; //尝试把第row行的皇后放在i列上
  27.          for(j=0;j<row;j++) //检验是否与前面已放好的皇后冲突
  28.          {
  29.              if(line[row]==line[j]||line[row]-row==line[j]-j||line[row]+row==line[j]+j)
  30.              {
  31.                  ok=0;
  32.                  break; //,跳出最内层循环如果冲突,停止搜索,返回上一级递归回溯。回溯法高效的关键。
  33.              }
  34.          }
  35.          if(ok)
  36.              search(row+1);
  37.      }
  38. }



 

 

阅读(5727) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~