Chinaunix首页 | 论坛 | 博客
  • 博客访问: 77243
  • 博文数量: 32
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 284
  • 用 户 组: 普通用户
  • 注册时间: 2015-04-26 14:00
个人简介

有梦想的人,正在努力

文章分类

全部博文(32)

文章存档

2015年(32)

我的朋友

分类: C/C++

2015-04-30 23:19:12

这道题是典型的深搜类型的题。直接贴代码了。
但是有个需要注意的是,要先打表,不然会超时。


  1. #include <iostream>
  2. #include <memory.h>
  3. using namespace std;
  4. int flag[10][10];
  5. int cnt, s;
  6. void dfs(int depth);
  7. void mark_for_unavailable(int, int);
  8. void mark_for_available(int, int);
  9. bool isAvailable(int, int);
  10. int main()
  11. {
  12.     //因为N<=10, 所以这里先打表,之前没打表,数据量很大。超时了。
  13.     int num[11];
  14.     for(s = 1; s <= 10; ++s)
  15.     {
  16.         cnt = 0;
  17.         memset(flag, -1, sizeof(flag));
  18.         dfs(0);
  19.         num[s] = cnt;
  20.     }

  21.     int n;
  22.     while(cin >> n)
  23.     {
  24.         if(0 == n)
  25.             break;
  26.         cout << num[n] << endl;
  27.     }
  28.     return 0;
  29. }

  30. void dfs(int depth)  //深搜
  31. {
  32.     for(int i = 0; i < s; i++)
  33.     {
  34.         if(isAvailable(depth, i))
  35.         {
  36.             if(depth == s - 1) {cnt++; return;}
  37.             mark_for_unavailable(depth, i);
  38.             dfs(depth + 1);
  39.             mark_for_available(depth, i);
  40.         }
  41.     }
  42. }

  43. void mark_for_unavailable(int i, int j) //标记行列,对角线为不可放皇后
  44. {
  45.     for(int k = i; k < s; ++k) if(-1 == flag[k][j]) flag[k][j] = i;
  46.     for(int k = 0; k < s; ++k) if(-1 == flag[i][k]) flag[i][k] = i;
  47.     for(int k = i, p = j; k < s && p >= 0; ++k, --p) if(-1 == flag[k][p]) flag[k][p] = i;
  48.     for(int k = i, p = j; k < s && p < s; ++k, ++p) if(-1 == flag[k][p]) flag[k][p] = i;
  49. }
  50. void mark_for_available(int i, int j)  //取消标记
  51. {
  52.     for(int k = i; k < s; ++k) if(i == flag[k][j]) flag[k][j] = -1;
  53.     for(int k = 0; k < s; ++k) if(i == flag[i][k]) flag[i][k] = -1;
  54.     for(int k = i, p = j; k < s && p >= 0; ++k, --p) if(i == flag[k][p]) flag[k][p] = -1;
  55.     for(int k = i, p = j; k < s && p < s; ++k, ++p) if(i == flag[k][p]) flag[k][p] = -1;
  56. }
  57. bool isAvailable(int i, int j) //判断是否可以放皇后
  58. {
  59.     if(-1 == flag[i][j])
  60.         return true;
  61.     return false;
  62. }

另外在该题的Discuss里面看到一份很牛的代码,我没怎么看懂。
使用的是位运算。

  1. #include <iostream>
  2. #include <cstdio>
  3. using namespace std;
  4. int sum,upperlim,n;
  5. int ans[15];
  6. void queen(int row, int ld, int rd)
  7. {
  8.     int pos,p;
  9.     if(row != upperlim)
  10.     {
  11.         pos = upperlim & (~(row | ld | rd));
  12.         while(pos != 0)
  13.         {
  14.             p = pos & (-pos);
  15.             pos = pos - p;
  16.             queen(row+p, (ld+p)<<1, (rd+p)>>1);
  17.         }
  18.     }
  19.     else
  20.         sum++;
  21. }
  22. int main()
  23. {
  24.     for(int i=1; i<=10; i++)
  25.     {
  26.         upperlim = (1 << i) - 1;
  27.         sum = 0;
  28.         queen(0,0,0);
  29.         ans[i] = sum;
  30.     }
  31.     while(scanf("%d",&n),n)
  32.     {
  33.         cout<<ans[n]<<endl;
  34.     }
  35.     return 0;
  36. }


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