八皇后
前言
作者 : mzq
邮箱: 2631194340@qq.com
题目
检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有 且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。
理解
解法有两种,但是第一种复杂度太高,容易T
第一种
//条件可以用y-x 跟y+x来看
c[cur] == c[j] || j - c[j] == cur - c[cur] || j + c[j] == cur + c[cur]
第二种
//用于将对角线跟所在的列做标记,y-x可能为负所以要加上n cur-c[cur]==cur-i
vis[0][i] = vis[1][cur + i] = vis[2][cur - i + n] = 1;
searchb(cur + 1);
vis[0][i] = vis[1][cur + i] = vis[2][cur - i + n] = 0;
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
//计算解的个数
int sum = 0;
//n皇后
int n = 0;
//输出前三种解法
int out = 3;
//用来存放每一行的皇后
int c[13];
//这里是第一种方法
void search(int cur)
{
//sum记录的是答对的次数
if (cur == n)
{
sum++;
if (out)
{
for (int i = 0; i < n; i++)
{
printf("%d ",c[i]+1);
}
out--;
printf("\n");
}
}
else
{
for (int i = 0; i < n; i++)
{
int ok = 1;
//在对应的行的每一列尝试
c[cur] = i;
for (int j = 0; j < cur; j++)
{
//利用y=x 跟 y=-x
if (c[cur] == c[j] || j - c[j] == cur - c[cur] || j + c[j] == cur + c[cur])
{
ok = 0;
break;
}
}
//如果经过循环后可以
if (ok)
{
search(cur + 1);
}
}
}
}
//这里是第二种方法
int vis[3][100] = {0};
void searchb(int cur)
{
if (cur == n)
{
sum++;
if (out)
{
for (int i = 0; i < n; i++)
{
printf("%d ", c[i] + 1);
}
out--;
printf("\n");
}
}
else
{
//判断
for (int i = 0; i < n; i++)
{
if (!vis[0][i] && !vis[1][cur + i] && !vis[2][cur - i + n])
{
c[cur] = i;
//用于将对角线跟所在的列做标记
vis[0][i] = vis[1][cur + i] = vis[2][cur - i + n] = 1;
searchb(cur + 1);
vis[0][i] = vis[1][cur + i] = vis[2][cur - i + n] = 0;
}
}
}
}
int main()
{
scanf("%d",&n);
searchb(0);
printf("%d\n",sum);
system("pause");
return 0;
}