N皇后
来源:互联网 发布:单机版数据库 编辑:程序博客网 时间:2024/06/09 22:54
对于N皇后问题, 用回溯的方法很容易理解, 但是在判重的时候容易超时,因此判重的的方法很重要,下面是我写的三段关于N皇后的代码,只有最后一段在QDUOJ上过了。
第一段:判重方法很蹩脚
#include <stdio.h>#define M 10000000 int n = 0, num = 0, a[M], array[20][20], count; void find(int m);int zero(int m, int i); int main(){ scanf("%d", &n); getchar(); find(1); printf("%d\n", num); return 0;} void find(int m){ int i, x; if(m > n) { num++; if(num <= 3) { for(i = 0; i < n; i++) printf("%d ", a[i]); printf("\n"); } } else { for(i = 1; i <= n; i++) { x = zero(m, i); if(x == 1 && array[m][i] == 0) { a[count++] = i; array[m][i] = 1; find(m+1); array[m][i] = 0; count--; a[count] = -1; } } }} int zero(int m, int i){ int j = 0, x, y, flag[4] = {0}; if(m == 1) return 1; x = m - 1; for(x; x >= 0; x--) { if(array[x][i] == 1) flag[0] =1; } x = m - 1; y = i - 1; for(x, y; x >=0 && y >= 0; x--, y--) { if(array[x][y] == 1) flag[2] = 1; } x = m - 1; y = i + 1; for(x, y; x >= 0 && y <= n; x--, y++) { if(array[x][y] == 1) flag[3] = 1; } for(x = 0; x < 4; x++) { if(flag[x] == 1) return 0; } return 1;}
第二种方法:从网上取了取经,用一位数组存储棋盘,但是判重的时候还是需要循环
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#include <time.h>#define M 100000int array[M], n, num;int find(int row);int zero(int row, int col);int main(){int start, end;scanf("%d", &n);getchar();start = clock();find(1);end = clock();printf("%d\n", num);printf("time is %d\n", end - start);return 0;}int zero(int row, int col){int i;if(row == 0)return 1;for (i = 1; i <= row; ++i) //对棋盘进行扫描 { if (array[i] == col || abs(i - row) == abs(array[i] - col)) //判断列冲突与斜线上的冲突 return 0; } return 1; }int find(int m){int i, j;if(m > n){num++;if(num <= 3){for(i = 1; i <= n; i++)printf("%d ", array[i]);printf("\n");}}else{for(i = 0; i <= n; i++){j = zero(m, i);if(j == 1){array[m] = i;find(m+1);array[m] = 0;}}}}
第三种方法:参考的《算法竞赛入门经典》,方法很巧妙
#include <stdio.h>int num = 0, n, array[3][30] = {0}, a[20];void find(int cur);int main(){scanf("%d", &n);getchar();find(0);printf("%d\n", num);return 0;} void find(int cur){int i, j;if(cur == n){num++;if(num <= 3){for(j = 0; j < n - 1; j++)printf("%d ", a[j] + 1);printf("%d\n", a[n - 1] + 1);return ;}}else{for(i = 0; i < n; i++)if(!array[0][i] && !array[1][cur + i] && !array[2][cur - i + n]){//array[0][i]标记的是列//array[1][cur + i]标记的是斜对角线(行与列相加是相等的)//array[2][cur - i + n]标记的是主对角线(行与列相减是相等的, 加n是为了避免cur < i的情况出现)a[cur] = i;array[0][i] = 1;array[1][cur + i] = 1;array[2][cur - i + n] = 1;find(cur+1);array[0][i] = 0;array[1][cur + i] = 0;array[2][cur - i + n] = 0;}}}
- n皇后
- N皇后
- N 皇后
- n皇后
- n皇后
- N皇后
- N皇后
- n皇后
- n 皇后
- N皇后
- N皇后
- N皇后
- N皇后
- n皇后
- N皇后
- N皇后
- N皇后
- N皇后
- eclipse安装插件
- 更新证书错误Code Sign error: Provisioning profile ‘XXXX'can't be found
- ENC28J60学习笔记——第3部分
- 基于XMPP协议(openfire服务器)的消息推送实现
- NYOJ-600-花儿朵朵-2013年08月21日19:14:49
- N皇后
- Key Paths
- C语言中字符串如何转换为二进制、八进制、十进制、十六进制
- 大学生活的完美句点
- 多线程和多进程的区别(小结)
- 如何利用Google机器人进行SQL攻击
- 音量调大时出现爆音的问题解决(也是从我的新浪博客转来的)
- Java 空指针异常(java.lang.NullPointerException)
- hibernate缓存