N皇后问题(hdu2553)
2014-05-08 17:29
381 查看
N皇后问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7656 Accepted Submission(s): 3446
[align=left]Problem Description[/align]
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
[align=left]Input[/align]
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
[align=left]Output[/align]
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
[align=left]Sample Input[/align]
1 8 5 0
[align=left]Sample Output[/align]
1 92 10
在学搜索算法,无意间看到这个问题表示很纠结,查书找资料写出了第一种回溯递归结果超时了;
代码:
#include<iostream> #include<stdio.h> #include<string> #include<queue> #include<string.h> #include<cmath> #include<algorithm> #include<math.h> using namespace std; int c[11],tot,n; void serch(int cur) { int i,j; if(cur==n)tot++; else { for(i=0;i<n;i++) { int ok=1; c[cur]=i; for(j=0;j<cur;j++) if(c[cur]==c[j]||cur-c[cur]==j-c[j]||cur+c[cur]==j+c[j])//判断是否可以满足条件,如果不满足ok=0 { ok=0; break; } if(ok)serch(cur+1);//满足时继续回溯 } } } int main() { while(cin>>n,n) { memset(c,0,sizeof(c)); tot=0; serch(0); cout<<tot<<endl; } }第二种回溯是用二维数组直接比较,可还是超时0.0(这题咋那么难!)
代码:
#include<iostream> #include<stdio.h> #include<string> #include<queue> #include<string.h> #include<cmath> #include<algorithm> #include<math.h> using namespace std; int tot,n,c[2500]; bool vis[3][2500]; void serch(int cur) { int i,j; if(cur==n)tot++; else { for(i=0;i<n;i++) { if(!vis[0][i]&& !vis[1][cur+i]&& !vis[2][cur-i+n]) { c[cur]=i; vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1; serch(cur+1); vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0; } } } } int main() { while(cin>>n,n) { memset(c,0,sizeof(c)); memset(vis,0,sizeof(vis)); tot=0; serch(0); cout<<tot<<endl; } }在网上搜到个代码15ms过的,和第一个代码很相似,时间短的原因就是他打表过的!无语啊!
代码:
#include<iostream> #include<stdio.h> #include<string> #include<queue> #include<string.h> #include<cmath> #include<algorithm> #include<math.h> using namespace std; int n,c[11],ans[11],sum; bool judge(int cur) { for(int i=1;i<cur;i++) { if(c[cur]==c[i]||abs(c[cur]-c[i])==cur-i)//判断不同列,不同对角线 return 0; } return 1; } void dfs(int cur) { for(int i=1;i<=n;i++) { c[cur]=i; if(judge(cur)) { if(cur==n) sum++; else dfs(cur+1); } } } int main() { for(int i=1;i<11;i++)//就这个打表过程! { sum=0; n=i; dfs(1); ans[i]=sum; } while(cin>>n,n) { cout<<ans <<endl; } }
相关文章推荐
- TI C66x DSP 系统events及其应用 - 4.3(Exception handle)
- ios 沙盒 NSCoding 归档 数据存储
- java环境变量配置(windows7)
- 从K近邻算法、距离度量谈到KD树、SIFT+BBF算法
- Eclipse调试Java的10个技巧
- 输出两字符串最大相同部分——C面试题
- 针对list集合排序
- Android Compatibility package 兼容性开发套件
- 深入理解Javascript闭包概念
- WebBrowser嵌入对话框中,回车键不响应
- 关于青春
- POJ1742 coins
- hello world 级别模块程序
- 据说这是改进版顺序链表
- github fork开源项目后如何与源项目保持同步
- jquery的show/hide性能测试
- 时间去哪了
- c/c++内存泄露
- poi excel自动转换成javabean 支持引用类型属性二级转换
- [知识积累]centos命令记录 lsblk