Q - New N皇后问题2
原题地址
1.大概题意:给定棋盘大小以及一个皇后位置,求摆放方案。
2.思路分析:
和普通的N皇后问题一样,只不过之前一个已经确定而已,核心代码如下:
3.代码部分:
Check 函数,用来检查上下左右以及对角线是否满足要求。一切都没有冲突就返回 true ,很好理解。
Dfs 函数。这里的 ans数组是用来存储答案,注意题目的要求是输出行号从小到大排列时对应的列号,那么就按行来进行 dfs 即可。当到达 n 时就是结束标志,记录答案,并将 res++;否则,就是一次遍历,注意,如果到达了原先放置好的皇后的行号时,那么我们的列号也必须是 sy ,然后在判断 check 是否满足即可。
主程序。这里预处理将 ans[ i ][ sx ]=sy ,然后输出答案即可。
#include <bits/stdc++.h>
using namespace std;
const int aa = 15;
const int MAXN = 1000005;
int a[aa][aa];
int visx[aa];
int visy[aa];
int n ;
int res ;
int ans[MAXN][aa];
int tmp[aa];
int sx, sy;
bool check( int x, int y ){
if( visx[x] ) return false;
if( visy[y] ) return false;
int xx = x - 1;
int yy = y - 1;
while( xx >= 0 && yy >= 0 ){
if( a[xx][yy] ) return false;
xx-- ; yy--;
}
xx = x + 1 ;
yy = y - 1 ;
while( xx < n && yy >= 0 ){
if( a[xx][yy] ) return false;
xx++ ; yy--;
}
xx = x - 1 ;
yy = y + 1 ;
while( xx >= 0 && yy < n ){
if( a[xx][yy] ) return false;
xx-- ; yy++;
}
xx = x + 1 ;
yy = y + 1 ;
while( xx < n && yy < n ){
if( a[xx][yy] ) return false;
xx++ ; yy++;
}
return true;
}
void dfs( int r ){
if( r == n ){
for( int i = 0 ; i < n ; i++ ){
ans[res][i] = tmp[i];
}
res ++ ;
return;
}
for( int i = 0 ; i < n ; i ++ ){
if( r == sx ){
if( i != sy ) continue;
}
if( check( r , i ) ){
a[r][i] = 1;
tmp[r] = i;
visx[r] = 1;
visy[i] = 1;
dfs( r + 1 );
visx[r] = 0;
visy[i] = 0;
a[r][i] = 0;
}
}
}
int main(){
res = 0;
scanf("%d",&n);
scanf("%d%d",&sx,&sy);
sx-- ; sy-- ;
memset( a , 0 ,sizeof(a) );
dfs(0);
printf("%d\n",res);
for( int i = 0 ; i < res ; i++ ){
ans[i][sx] = sy;
}
for( int i = 0 ; i < res ; i++ ){
for( int j = 0 ; j < n ; j++ ){
printf("%d ",ans[i][j] + 1 );
}
printf("\n");
}
return 0 ;
}