递归与回溯 HDOJ 2553 N皇后问题 1016 Prime Ring Problem
2017-01-26 23:29
531 查看
题目传送门:
http://acm.hdu.edu.cn/showproblem.php?pid=2553
http://acm.hdu.edu.cn/showproblem.php?pid=1016
递归是程序调用自身的一种技巧,在牺牲空间复杂度的同时,带来代码上的简明和思想上的畅快。
回溯往往与递归同时出现,比起枚举,回溯的效率高一些,回溯的重点在于如何从当前状态返回上一状态。
八皇后问题和素数环问题是递归与回溯中最典型的两个问题。
2553:N皇后问题
N皇后问题是八皇后问题的拓展,与八皇后问题本质上是一样的。
1016:素数环
http://acm.hdu.edu.cn/showproblem.php?pid=2553
http://acm.hdu.edu.cn/showproblem.php?pid=1016
递归是程序调用自身的一种技巧,在牺牲空间复杂度的同时,带来代码上的简明和思想上的畅快。
回溯往往与递归同时出现,比起枚举,回溯的效率高一些,回溯的重点在于如何从当前状态返回上一状态。
八皇后问题和素数环问题是递归与回溯中最典型的两个问题。
2553:N皇后问题
N皇后问题是八皇后问题的拓展,与八皇后问题本质上是一样的。
#include <iostream> #include <cmath> using namespace std; int f[15], cnt, n; int isplace(int m) { for (int i = 1; i < m; ++i) { // 判断是否和已有棋子冲突,只需判断列和对角线即可 if (f[m] == f[i] || abs(m - i) == abs(f[m] - f[i])) return 0; } return 1; } //m是当前正在放第几个棋子,并把这个棋子放在第m行 void dfs(int m) { // 递归出口 if (m == n + 1) { cnt ++; return ; } // 从第一列枚举到最后一列 for (int i = 1; i <= n; ++ i) { f[m] = i; // 这一步在枚举的同时也包含了回溯 // 若可以放置,则放置下一个棋子 if (isplace(m)) { dfs(m + 1); } } return ; } int main(int argc, char const *argv[]) { int i,j,ans[15]; //先打表,不然会超时 for (int i = 1; i <= 10; ++ i) { cnt = 0; n = i; dfs(1); ans[i] = cnt; } int t; while (cin >> t, t){ cout << ans[t] << endl; } return 0; }
1016:素数环
#include <iostream> #include <cmath> #include <cstring> #include <cstdio> using namespace std; int isok[25], f[25]; // 判断一个数是否是素数 int IsPrime(int n) { if (n == 2) return 1; if (n % 2 == 0) return 0; for (int i = 3; i <= sqrt(n); i += 2) { if (n % i == 0) return 0; } return 1; } void dfs(int cur, int n) { // 递归出口 if (cur == n + 1) { /* 需要注意的是,所有数字放好之后还要判断首尾两个 数的和是否是素数 */ if (IsPrime(f + f[1]) ) { cout << f[1]; for (int i = 2; i <= n; ++i) { cout << " " << f[i]; } cout << endl; } return ; } for (int i = 2; i <= n; ++i) { if ( isok[i] && IsPrime(i + f[cur - 1]) ) { f[cur] = i; // 标记当前数字已被使用 isok[i] = 0; dfs(cur + 1, n); // 回溯,重新标记当前数字未被使用 isok[i] = 1; } } return ; } int main(int argc, char const *argv[]) { int n, cnt = 1; f[1] = 1; while (cin >> n) { memset(isok,-1,sizeof(isok)); isok[1] = 0; printf("Case %d:\n",cnt ++); dfs(2,n); cout << endl; } return 0; }
相关文章推荐
- hdoj--1016--Prime Ring Problem(递归回溯)
- hdoj--1016--Prime Ring Problem(递归回溯)
- hdoj--1016--Prime Ring Problem(递归回溯)
- hdoj 1016 Prime Ring Problem 深搜回溯
- HDOJ1016 Prime Ring Problem (DFS,回溯)
- HDOJ/HDU 2553 N皇后问题 回溯加递归
- hdoj1016 Prime Ring Problem (入门回溯) 题解
- HDOJ 1016 Prime Ring Problem(dfs+回溯)
- 杭电OJ(HDOJ)1016题:Prime Ring Problem(DFS问题)
- hdoj problem 1016 Prime Ring Problem(素数环&&素数问题+DFS(回溯法))
- hdoj 1016 Prime Ring Problem 【DFS】
- HDOJ 1016 Prime Ring Problem!!
- HDOJ 1016 Prime Ring Problem(素数环 - 深搜)
- HDOJ1016 Prime Ring Problem
- HDU-#1016 Prime Ring Problem(DFS+回溯)
- HDU 1016 Prime Ring Problem(DFS回溯)
- UVA - 524 Prime Ring Problem (经典回溯问题)
- HDOJ 1016 HDU 1016 Prime Ring Problem ACM 1016 IN HDU
- hdu 1016 Prime Ring Problem(回溯)
- hdu/hdoj 1016 Prime Ring Problem