您的位置:首页 > 其它

N皇后

2013-11-11 01:15 309 查看
全排列思想先以八皇后为例来说:在棋盘上放置八个皇后,使得他们互不攻击,此时每个皇后的攻击范围为同行同列和对角线,要求找出所有的解。分析:8行8列,以行来看,每行必有一个皇后,去看将每行的那个皇后放在哪个位置不会有列冲突和对角线冲突。因为每一列有且仅有一个,所以可以生成关于一个“列”的全排列。分析一下坐标(i, j)的关系:右对角线的范围,即: j - i,是-7~7;左对角线的范围,即:i+ j,是2 ~16;思路1:直接利用全排列的思想,只是在else的if判断条件中多了列和两个对角线的判断;思路2:使用标记数组:列标记数组Col[ ] , 左对角线Ldia[ ]和右对角线Rdia[ ]标记数组, 其中对右对角线做一下处理,i - j + 8,使其变为正数,对应到Rdia[ ]数组中;应该特别注意这三个标记数组的对应关系和作用;通过的不超时代码(思路2)如下
#include<stdio.h>int total = 0;int A[15], Col[15], Rdia[30], Ldia[30];void queen(int n, int cur);int main(void){int n;//    printf("请输入皇后的个数:\n");scanf("%d", &n);queen(n, 1);printf("%d\n", total);return 0;}void queen(int n, int cur){int i, j;if(cur == n + 1)                        //n个皇后找到对应位置,此时进入queen(8, A, 9);{total++;if(total <= 3){//for(i = 1; i < n; i++)printf("%d ", A[i]);printf("%d", A);printf("\n");}}else{for(i = 1; i <= n; i++)          //为第cur行的皇后在 1-n 中找到合适的列{if(Col[i] == 0 && Rdia[i - cur + 8] == 0 && Ldia[i + cur] == 0){A[cur] = i;Col[i] = 1;Rdia[i - cur + 8] = 1;Ldia[i + cur] = 1;queen(n,cur + 1);Col[i] = 0;Rdia[i - cur + 8] = 0;Ldia[i + cur] = 0;}//if}//for}//else}
做法正确但是超时的代码(思路1)
#include<stdio.h>int total = 0;int A[100];void queen(int n, int *A, int cur);int main(void){int n;printf("请输入皇后的个数:\n");scanf("%d", &n);queen(n, A, 1);printf("%d\n", total);return 0;}void queen(int n, int *A, int cur){int i, j;if(cur == n + 1)						//n个皇后找到对应位置,此时进入queen(8. A, 9);{total++;if(total <= 3){for(i = 1; i <= n; i++)printf("%d ", A[i]);printf("\n");}}else{for(i = 1; i <= n; i++)			//为第cur行的皇后在 1-n 中找到合适的列{int ok = 1;A[cur]  = i;for(j = 1; j < cur; j++)	//判断前cur - 1行的列、对角线中,是否有与第cur行的列、对角线冲突的;{if(A[cur] == A[j] || cur - A[cur] == j - A[j] || cur + A[cur] == j + A[j]){ok = 0;break;}}if(ok == 1){queen(n, A, cur + 1);}}}}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: