P1219 [USACO1.5]八皇后 Checker Challenge

一道很经典的搜索回溯题

思路

考虑到每一行只能够放一个,并且所有行的皇后都不放在同一列上,还要考虑皇后不在同一斜线上

img

(图片来自互联网,侵删)

用三个数组表示各行,各斜线是否被占,用x+yx-y+15表示不同方向斜线上的被占的情况,(x-y应考虑负值)

若被占领,则进行回溯。

代码实现

#include <cstdio>

using namespace std;
const int maxn = 101;
int n, sum = 0, ans[maxn] = {};
int check1[maxn] = {},check2[maxn] = {},check3[maxn] = {};
/* check[][0] check[][1] check[][2] 分别用来记录y,x+y,x-y+15是否被占用*/

void print() {
  for (int i = 1; i <= n; ++i) {
    printf("%d ", ans[i]);
  }
  printf("\n"); 
  return ;
}

void dfs(int line) {
  if(line > n) {
  //如果行数超过矩阵大小,则方案成立,总方案数+1 
    sum++;
    if (sum <= 3) //将前三种方案输出 
      print();
    return ;
  }
  for (int i = 1; i <= n; ++i) {
    if(check1[i] == 0 && check2[line + i] == 0 && check3[line - i + 15] == 0) {
      ans[line] = i;
      check1[i] = 1; check2[line + i] = 1; check3[line - i + 15] = 1;
      dfs(line + 1);
      check1[i] = 0; check2[line + i] = 0; check3[line - i + 15] = 0;
    }
  }
}

int main() {
  scanf("%d", &n);
  dfs(1);//从第一行开始枚举 
  printf("%d", sum);//输出总方案数 
  return 0;
} 
posted @ 2020-07-06 09:18  柠月与梦  阅读(368)  评论(0编辑  收藏  举报