《ACM程序设计》例题解析-N皇后问题

来源:互联网 发布:河北网络公益广告大赛 编辑:程序博客网 时间:2024/04/30 16:38

N皇后问题

题目大意

经典问题,N个皇后放在N*N的棋盘,互不攻击。

思路

回溯,每行放一个,O(N!)

格子合法的判断

数组

?列位置 col[N]
?左右对角线 lr[2*N-1]
?右左对角线 rl[2*N-1]

y-x+n-1                    

7891011121314678910111213567891011124567891011345678910234567891234567801234567x+y

0123456712345678234567893456789104567891011567891011126789101112137891011121314

屏蔽位

row

101010111010111010

ld

100100110100101000rd

000111010111001011


*图片来源于Matrix67的Blog

代码

数组判断格子合法

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <time.h>#include <assert.h>typedef __int64 LL;#define N 14int col[N],lr[2*N-1],rl[2*N-1];int cnt;int dfs(int *a,int k,int n){int i;if(k==n){cnt++;/*if(cnt < 10) {for(i=0;i<n;i++) printf("%d ",a[i]);printf("\n");}*/}else{for(i=0;i<n;i++){if(!col[i] && !lr[i-k+n-1] && !rl[k+i]){a[k] = i;col[i] = lr[i-k+n-1] = rl[k+i] = 1;dfs(a,k+1,n);col[i] = lr[i-k+n-1] = rl[k+i] = 0;}}}}int main(){int a[N];time_t begin,end;begin = clock();dfs(a,0,14);printf("%d\n",cnt);end = clock();printf("time:%.3f\n ",(end - begin)*1.0/CLOCKS_PER_SEC);return 0;}

利用屏蔽位

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <time.h>#include <assert.h>typedef __int64 LL;int cnt = 0;void dfs(int *a,int k,int n,int c,int l,int r){    int i,mask,t;    if(k==n){        cnt++;        /*if(cnt < 10) {            for(i=0;i<n;i++) printf("%d ",a[i]);            printf("\n");        }*/    }    else{        mask = c | l | r;        for(i=0;i<n;i++){            t = 1<<i;            if(~mask&t){                a[k] = i;                                dfs(a,k+1,n,c|t,(l|t)<<1,(r|t)>>1);            }        }    }    }int main(){    int a[20];    time_t begin,end;    begin = clock();    dfs(a,0,14,0,0,0);    printf("%d\n",cnt);    end = clock();    printf("time:%.3f\n ",(end - begin)*1.0/CLOCKS_PER_SEC); //296    return 0;}



原创粉丝点击