题目描述
检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。
上面的布局可以用序列2 4 6 1 3 5来描述,第i个数字表示在第i行的相应位置有一个棋子,如下:
行号 1 2 3 4 5 6
列号 2 4 6 1 3 5
这只是跳棋放置的一个解。请编一个程序找出所有跳棋放置的解。并把它们以上面的序列方法输出。解按字典顺序排列。请输出前3个解。最后一行是解的总个数。
输入输出格式
输入格式:
一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的。
输出格式:
前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。
输入输出样例
输出样例#1:
【题目链接】:传送门
2 4 6 1 3 5 3 6 2 5 1 4 4 1 5 2 6 3 4
【题目链接】:传送门
【题意】:八皇后
经典的搜索问题,这个是抄袭了题解中的某位大佬的写法的。因为要是给我写可能会更加复杂,
看到别人的写法十分简洁,决定模仿别人的写一遍。
根据皇后的走向来加判断:
皇后可以在同一列走:
首先,根据列为单位进行处理,因为每一列必须不同的。
皇后可以在同一行走:
我们选择元素必须是不重复
皇后可以在对角线走:
所以在放之前加判断:就是之前放过 用For循环判断是否在对角线。
他们的关系就是差值相同就在同一个对角线
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 20; 4 int a[N],vis[N],n,Ans,F=3; 5 inline void dfs(int x){ 6 if( x == n+1 ){ 7 Ans ++ ; 8 if( F ){ 9 for(register int i=1;i<=n;i++){ 10 printf("%d%c",a[i],i==n?'\n':' '); 11 } 12 F--; 13 } 14 return ; 15 } 16 for(register int i=1;i<=n;i++){ 17 if(vis[i]==1) continue; 18 19 a[x] = i; 20 int f = 1 ; 21 for(int j=1;j<x;j++){ 22 if( i == a[j] || i-x == a[j]-j || i+x == a[j]+j ){ 23 f = 0;break; 24 } 25 } 26 if( f ){ 27 vis[i] = 1; 28 dfs(x+1); 29 vis[i] = 0; 30 } 31 } 32 } 33 int main() 34 { 35 scanf("%d",&n); 36 dfs(1); 37 printf("%d\n",Ans); 38 return 0; 39 }