八皇后问题(bjfu 1275)
2015-08-27 09:13
204 查看
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
八皇后问题是一个以国际象棋为背景的问题:如何能够在
8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当 n = 1 或 n ≥ 4 时问题有解。
题解一(比较粗暴,4960ms):
题解二(优化数组,889ms):
题解三(0ms,直接打表,看看就好):
[align=left][/align]
八皇后问题是一个以国际象棋为背景的问题:如何能够在
8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当 n = 1 或 n ≥ 4 时问题有解。
题解一(比较粗暴,4960ms):
#include<stdio.h> #include<iostream> #include<string> #include<string.h> #include<algorithm> #include<vector> #include<time.h> #include<queue> #include<stack> #include<iterator> #include<math.h> #include<stdlib.h> #include<limits.h> #include<map> #include<memory.h> //#define ONLINE_JUDGE #define eps 1e-8 #define INF 0x7fffffff //INT_MAX #define inf 0x3f3f3f3f //int?????????????????? #define FOR(i,a) for((i)=0;i<(a);(i)++) //[i,a); #define MEM(a) (memset((a),0,sizeof(a))) #define sfs(a) scanf("%s",a) #define sf(a) scanf("%d",&a) #define sfI(a) scanf("%I64d",&a) #define pf(a) printf("%d\n",a) #define pfI(a) printf("%I64d\n",a) #define pfs(a) printf("%s\n",a) #define sfd(a,b) scanf("%d%d",&a,&b) #define sft(a,b,c)scanf("%d%d%d",&a,&b,&c) #define for1(i,a,b) for(int i=(a);i<b;i++) #define for2(i,a,b) for(int i=(a);i<=b;i++) #define for3(i,a,b)for(int i=(b);i>=a;i--) #define MEM1(a) memset(a,0,sizeof(a)) #define MEM2(a) memset(a,-1,sizeof(a)) #define LL __int64 const double PI = acos(-1.0); template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; } template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; } template<class T> inline T Min(T a, T b) { return a < b ? a : b; } template<class T> inline T Max(T a, T b) { return a > b ? a : b; } using namespace std; template<class T> T Mint(T a, T b, T c) { if (a>b) { if (c>b) return b; return c; } if (c>a) return a; return c; } template<class T> T Maxt(T a, T b, T c) { if (a>b) { if (c>a) return c; return a; } else if (c > b) return c; return b; } int T, n, cnt, tot; int c[10]; void search(int curr) { if (curr == n) tot++; for (int i = 0; i<n; i++) { c[curr] = i; int flag = 1; for (int j = 0; j<curr; j++) if (c[curr] == c[j] || curr - c[curr] == j - c[j] || curr + c[curr] == j + c[j])//判断列、对角线 { flag = 0; break; } if (flag) search(curr + 1); } } int main() { sf(T); int j = 1; while (T--) { sf(n); tot = 0; search(0); printf("Case %d: %d\n", j++, tot); } return 0; }
题解二(优化数组,889ms):
#include<stdio.h> #include<iostream> #include<string> #include<string.h> #include<algorithm> #include<vector> #include<time.h> #include<queue> #include<stack> #include<iterator> #include<math.h> #include<stdlib.h> #include<limits.h> #include<map> #include<memory.h> //#define ONLINE_JUDGE #define eps 1e-8 #define INF 0x7fffffff //INT_MAX #define inf 0x3f3f3f3f //int?????????????????? #define FOR(i,a) for((i)=0;i<(a);(i)++) //[i,a); #define MEM(a) (memset((a),0,sizeof(a))) #define sfs(a) scanf("%s",a) #define sf(a) scanf("%d",&a) #define sfI(a) scanf("%I64d",&a) #define pf(a) printf("%d\n",a) #define pfI(a) printf("%I64d\n",a) #define pfs(a) printf("%s\n",a) #define sfd(a,b) scanf("%d%d",&a,&b) #define sft(a,b,c)scanf("%d%d%d",&a,&b,&c) #define for1(i,a,b) for(int i=(a);i<b;i++) #define for2(i,a,b) for(int i=(a);i<=b;i++) #define for3(i,a,b)for(int i=(b);i>=a;i--) #define MEM1(a) memset(a,0,sizeof(a)) #define MEM2(a) memset(a,-1,sizeof(a)) #define LL __int64 const double PI = acos(-1.0); template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; } template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; } template<class T> inline T Min(T a, T b) { return a < b ? a : b; } template<class T> inline T Max(T a, T b) { return a > b ? a : b; } using namespace std; template<class T> T Mint(T a, T b, T c) { if (a>b) { if (c>b) return b; return c; } if (c>a) return a; return c; } template<class T> T Maxt(T a, T b, T c) { if (a>b) { if (c>a) return c; return a; } else if (c > b) return c; return b; } #define maxn 200 bool vis[3][maxn]; int n, T, tot; int search(int curr) { if (curr == n) tot++; else { for1(i, 0, n) { if (!vis[0][i] && !vis[1][curr+i] && !vis[2][curr-i+n]) { vis[0][i] = vis[1][curr+i] = vis[2][curr-i+n] = 1; search(curr + 1); vis[0][i] = vis[1][curr + i] = vis[2][curr - i + n] = 0; } } } return tot; } int main() { while (~sf(T)) { int j = 0; while (T--) { j++; sf(n); printf("Case %d: ", j); tot = 0; pf(search(0)); } } return 0; }
题解三(0ms,直接打表,看看就好):
[align=left][/align]
#include<stdio.h> #include<iostream> using namespace std; int T,n; int a[15]={1,0,0,2,10,4,40,92,352,724,2680,14200,73712}; int main() { scanf("%d",&T); int j=1; while(T--) { scanf("%d",&n); printf("Case %d: %d\n",j++,a[n-1]); } return 0; }
相关文章推荐
- Android UI设计——GridView控件
- 【POJ2060】Taxi Cab Scheme
- 消除HTTP瓶颈的SPDY
- memset ,memcpy 和strcpy 的区别
- 内部类
- ORACLE日期时间函数大全
- java多线程(八)为什么弃用stop和suspend
- FileToolkit 文件工具箱
- google_protobuf数据类型
- Android 从清单配置文件元数据中获取值
- WIFI工具移植之IW工具移植
- BZOJ 题目1031: [JSOI2007]字符加密Cipher(后缀数组sa简单应用)
- 欢迎使用CSDN-markdown编辑器
- 微信支付(APP)集成时碰到的问题(.net提示“无权限”、iOS跳转到微信支付页面中间只有一个“确定”按钮)
- 二叉树的下一个结点
- .NET Socket编程 超时时间的理解
- python包的安装与卸载
- POJ 2209 The King(水~)
- hdu 5411 CRB and Puzzle
- jenkins的Deploy Plugin插件的安装