Checker Challenge跳棋的挑战(n皇后问题)

Description

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

0   1   2   3   4   5   6
  -------------------------
1 |   | O |   |   |   |   |
  -------------------------
2 |   |   |   | O |   |   |
  -------------------------
3 |   |   |   |   |   | O |
  -------------------------
4 | O |   |   |   |   |   |
  -------------------------
5 |   |   | O |   |   |   |
  -------------------------
6 |   |   |   |   | O |   |
  -------------------------

上面的布局可以用序列2 4 6 1 3 5来描述,第i个数字表示在第i行的相应位置有一个棋子,如下: 行号 1 2 3 4 5 6 列号 2 4 6 1 3 5 这只是跳棋放置的一个解。请遍一个程序找出所有跳棋放置的解。并把它们以上面的序列方法输出。解按字典顺序排列。请输出前3个解。最后一行是解的总个数。 特别注意: 对于更大的N(棋盘大小N x N)你的程序应当改进得更有效。不要事先计算出所有解然后只输出,这是作弊。如果你坚持作弊,那么你登陆USACO Training的帐号将被无警告删除

Input

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

Output

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

Sample Input

6

Sample Output

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

HINT

题意:在n*n的棋盘上放置n个·棋子,要求每一行,每一列,包括左对角线,右对角线有且仅有一枚棋子,求有几种方法并输出前3种。

题解:翻译过来就是n皇后问题的裸题,此题的关键就是用3个数组记录该棋子的列,左右对角线棋子的状态,然后逐行搜索,用记录数组记录每行的状态就可以了。

#include<cstdio>
#include<cstring>
#include<stack>
#include<iostream>
#include<queue>
#include<algorithm>
#include<map>
#include<cmath>
#include<vector>
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
int m,n,cnt,ans;
int str[10000];
int vis[3][500];
int dis[500][500];
int di[4][2]= {{-1,0},{1,0},{0,-1},{0,1}};
map<ll,ll>::iterator it;
void init()
{
    cin>>m;
    memset(vis,0,sizeof(vis));
}
void output()
{
    for(int i=1;i<=m;i++)
    {
        printf("%d%c",str[i],i==m?'\n':' ');
    }
}
void dfs(int curx)
{
    if(curx>m)
    {
        ans++;
        if(ans<=3)
        output();
        return ;
    }
    for(int i=1;i<=m;i++)
    {
        if(!vis[0][i]&&!vis[1][curx+i]&&!vis[2][curx-i+m])//vis[0][i]表示该列是否有棋子,vis[1][i]表示该棋子的右对角线是否有棋子,vis[3][i]表示左对角线是否有棋子。
        {
            vis[0][i]=1;vis[1][curx+i]=1;vis[2][curx-i+m]=1;//状态标记
            str[curx]=i;//记录数组
            dfs(curx+1);
            vis[0][i]=0;vis[1][curx+i]=0;vis[2][curx-i+m]=0;//状态还原
 
        }
    }
}
int main()
{
    init();
    dfs(1);
    cout<<ans<<endl;
}

猜你喜欢

转载自www.cnblogs.com/moomcake/p/9703378.html