首页 > 其他分享 >P1219 八皇后(搜索)

P1219 八皇后(搜索)

时间:2023-02-17 12:54:35浏览次数:33  
标签:表示 int 样例 dfs 搜索 皇后 P1219 左下 1005


题目描述

检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。

P1219 八皇后(搜索)_ios

上面的布局可以用序列2 4 6 1 3 5来描述,第i个数字表示在第i行的相应位置有一个棋子,如下:

行号 1 2 3 4 5 6

列号 2 4 6 1 3 5

这只是跳棋放置的一个解。请编一个程序找出所有跳棋放置的解。并把它们以上面的序列方法输出。解按字典顺序排列。请输出前3个解。最后一行是解的总个数。

//以下的话来自usaco官方,不代表洛谷观点

特别注意: 对于更大的N(棋盘大小N x N)你的程序应当改进得更有效。不要事先计算出所有解然后只输出(或是找到一个关于它的公式),这是作弊。如果你坚持作弊,那么你登陆USACO Training的帐号删除并且不能参加USACO的任何竞赛。我警告过你了!

输入输出格式

输入格式:

 

一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的。

 

输出格式:

 

前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。

 

输入输出样例

输入样例#1: 复制


6


输出样例#1: 复制


2 4 6 1 3 5 3 6 2 5 1 4 4 1 5 2 6 3 4


#include <iostream>
#include <cstdio>
using namespace std;
int a[1005] ,b[1005] ,c[1005],d[1005] ;
// a表示行 b表示列 c表示从左下到右上 d表示从左上到右下
/*
这个题目,就是用的搜素和回溯的方法 ,


*/
int n ;
int ans = 0 ; //解的个数
void dfs(int i){
if(i>n ){
if(ans <3 ){
for(int j = 1 ;j <=n ; j++ ){
printf("%d ",a[j]);
}
printf("\n") ;
}
ans++ ;
return ;
}
else{
// 对于该行 ,考察对应列
// 其中i 表示所在行 , j 表示所在列 ;

// 还有一个问题 , 怎么表示两个对角线呢 ,
// 我们发现 从左下到右上行数和列数满足 i +j = C固定值
// 从右上到左下 行数和列数满足 i-j = 固定值
// i -j 可能为负数 ,所有我们加个 n 来调整
for(int j = 1 ; j<=n ; j++ ){
if( (!b[j])&& (!c[i+j]) && (!d[i-j+n])){ // 如果都没有冲突
// 就可以放旗子;
a[i] = j ; // 表示在第 i 行 第j 列放了皇后
b[j] = 1 ;
c[i+j] = 1 ;
d[i-j+n] = 1 ;
dfs(i+1) ; // 考察下一行
a[i] = 0 ;
b[j] = 0 ;
c[j+i ] = 0 ;
d[i-j+n] = 0;
}
}

}

}
int main(){

cin >> n ;
dfs(1) ;
cout<<ans;

return 0 ;
}

 

 

标签:表示,int,样例,dfs,搜索,皇后,P1219,左下,1005
From: https://blog.51cto.com/u_15970235/6063954

相关文章