搜索专题 - N皇后问题2

这里写图片描述

思路:
被cdoj的题吓怕了,一直害怕卡时间不敢交。。。
谁知道折腾了这么久还真是一道水题。。。
n皇后变种,一个固定的点必须放皇后。简单处理下就行了。
字典序回溯已经能够保证了。
Code:

#include <bits/stdc++.h>
using namespace  std;
const int AX = 13+6;
const int MAXN = 5e4+66;
int a[AX][AX];
int vis_x[AX];
int vis_y[AX];
int n ;
int res ;
int ans[MAXN][AX];
int tmp[AX];

int sx, sy;
bool check( int x, int y ){
    if( vis_x[x] ) return false;
    if( vis_y[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;
            vis_x[r] = 1;   
            vis_y[i] = 1;
            dfs( r + 1 );
            vis_x[r] = 0;
            vis_y[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 ;
}

猜你喜欢

转载自blog.csdn.net/FrankAx/article/details/80548995