N皇后问题(总结性)
来源:互联网 发布:淘宝卖龙年限定 编辑:程序博客网 时间:2024/06/06 15:03
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
1850
19210
很经典的n皇后问题。
第一个我放的代码是很经典而又简练的代码,但是放在vj上是超时,但是依然是通过回溯法做出来的
个人认为很巧妙
首先,进去函数后进行dfs对n皇后的竖坐标进行挨个位置枚举,x【i】=j也就是对坐标的标记,即第i行的竖坐标为j,然后对i ,j判断这个位置的可行性,枚举之间的已经确定好的数据即x[0]到x[i-1]所以的竖坐标值都不相同,且不再同一斜线,即相对应的的x的差值和相对应的的y的差值不同(斜线问题,仔细思考,也就是
abs(k-i)==abs(x[i]-x[k])很重要)如果ij可能,进入下一行进行枚举
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#define maxx 12using namespace std;int sum=0,n;int x[maxx];int judge(int k)//判断x[k]列k行是否合理{ int i; for(i=1;i<k;i++) { if(x[i]==x[k]||abs(k-i)==abs(x[i]-x[k])) { return 0; } } return 1;}int queen(int t){ if(t>n)//合适+1(可行解) sum++; else { for(int i=1;i<=n;i++) { x[t]=i;//t行i列 if(judge(t)) { queen(t+1); } } } return sum;}int main(){ int t; while(~scanf("%d",&n)) { memset(x,0,sizeof(x)); sum=0; if(n==0) break; else t=queen(1); printf("%d\n",t); } return 0;}
后来发现就是要把数据存入数组就可以解决超时问题,要注意,数据较小时,把数据答案存入数组,时间会减少不少
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;int book[15];int cnt;int judge(int k){ int i; for(i=1;i<k;i++) { if(book[i]==book[k]||abs(i-k)==abs(book[i]-book[k])) { return 0; } } return 1;}void dfs(int k,int n){ if(k>n) { cnt++; } else { for(int i=1;i<=n;i++) { book[k]=i; if(judge(k)) { dfs(k+1,n); } } }}int main(){ int ans[12],t; for(int i=1;i<=10;i++) { memset(book,0,sizeof(book)); cnt=0; dfs(1,i); ans[i]=cnt; } while(~scanf("%d",&t)) { if(t==0) break; else { printf("%d\n",ans[t]); } } return 0;}
第二种方法,简单的dfs,标记较多但是时间复杂度比较小
#include <stdio.h>#include <stdlib.h>#include <string.h>int book_x[15],book_y[15],book_z[15];int count;int judge(int i,int step){ int k; for(k=step-1;k>=1;k--) { if(book_y[k]==i+step) return 0; if(book_z[k]==i-step) return 0; } book_y[step]=i+step; book_z[step]=i-step; return 1;}void dfs(int step,int sum){ int i; if(step==sum+1) { count++; return; } for(i=1;i<=sum;i++) { if(book_x[i]==0&&judge(i,step)==1) { book_x[i]=1; dfs(step+1,sum); book_x[i]=0; } }}int main(){ int ans[15]; int i,n; for(i=1;i<=10;i++) { count=0; memset(book_x,0,sizeof(book_x)); memset(book_y,0,sizeof(book_y)); memset(book_z,0,sizeof(book_z)); dfs(1,i); ans[i]=count; } while(~scanf("%d",&n)) { if(n==0) break; printf("%d\n",ans[n]); } return 0;}
0 0
- N皇后问题(总结性)
- 八皇后问题(N皇后问题)
- N皇后问题(DFS)N皇后问题
- N皇后问题(回溯)
- N皇后问题(回溯)
- N皇后问题(DFS)
- N皇后问题(hdu2553)
- N皇后问题(递归)
- N皇后问题(2553)
- hdu2553(N皇后问题)
- N皇后问题(算法)
- n皇后问题(回溯)
- N*N皇后问题
- 八皇后 n皇后 问题
- 八皇后N皇后问题
- 八皇后问题(扩展:N皇后问题)
- 【算法分析】回溯法解八皇后问题(n皇后问题)
- 从八皇后问题到n皇后问题(leetcode)
- 【Java并发编程实战】-----“J.U.C”:CAS操作
- 使用 HTTP/2 加速 Node.js 应用
- 【Java并发编程实战】-----“J.U.C”:CLH队列锁
- redis for windows 开箱即用
- 学习总结
- N皇后问题(总结性)
- 【Java并发编程实战】----- AQS(一):简介
- Linux 如何使用 wget 下载整个网站
- 基础练习 查找整数
- Java代理详解
- 使用gradle实现Android项目debug版与release版共存
- socket(套接字)
- Attack on Titans(递推dp 条件限制)
- 【Java并发编程实战】----- AQS(二):获取锁、释放锁