HDU1016 Prime Ring Problem (回溯 + 剪枝)
2016-04-16 16:32
246 查看
本文链接:http://www.cnblogs.com/Ash-ly/p/5398684.html
题意:
给你一个数字N(N <= 20),要求你把这N个数组成一个环,环内的数字不能重复,左右相邻的两个的和是素数。给出最后的答案。
思路:
利用回溯剪枝算法,N个数,每个数有N种状态,枚举这N个状态,枚举过程中剪枝优化。
代码:
题意:
给你一个数字N(N <= 20),要求你把这N个数组成一个环,环内的数字不能重复,左右相邻的两个的和是素数。给出最后的答案。
思路:
利用回溯剪枝算法,N个数,每个数有N种状态,枚举这N个状态,枚举过程中剪枝优化。
代码:
#include <cstdio> #include <iostream> #include <cstring> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> using namespace std; const int MAXN = 43; int n; //素数表 int isprime[MAXN] = {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0}; //判断是否重复 int used[MAXN]; //素数环 int circle[MAXN]; //判断 第 key 个位置的数字是否合法 int check(int key) { if( used[ circle[key] ] ) //之前被用过 return 0; if(!isprime[ circle[key] + circle[key - 1] ])//和前面一个组成了非素数 return 0; if(key == n && !isprime[ circle[key] + 1 ])//最后一个数和第一个数的和也不能是素数 return 0; return 1; } void backtrack(int key) { if(key > n)//回溯完毕 打印结果 { for(int i = 1; i <= n; i++) cout <<(i == 1? "" : " ") << circle[i]; cout <<endl; } else { for(int i = 2; i <= n; i++) //这个位置一共有 n - 1 个状态,分别枚举 { circle[key] = i; if( check( key ) ) //剪枝处理 { used[i] = 1; //标记这个点已被用 backtrack(key + 1); used[i] = 0; //恢复现场 } } } } int main() { int kas = 1; while(cin >> n) { printf("Case %d:\n", kas++); memset(used, 0, sizeof(used)); memset(circle, 0, sizeof(circle)); circle[1] = 1; //第一个数字从 1 开始 backtrack(2); //从第二个数字开始求解 cout << endl; } return 0; }
相关文章推荐
- 移动端触屏滑动,JS事件
- python学习笔记三:解析html(HTMLParser、SGMLParser),并抓取图片
- 欢迎使用CSDN-markdown编辑器
- uvalive5848
- Android ListView控件选中item项,并保持选中状态
- 腾讯2面
- Win10下配置Hyper-V虚拟机通过NAT或桥接方式联网
- C++中的explicit关键字介绍
- mysql索引总结----mysql 索引类型以及创建
- Java 读写Properties配置文件
- 数据结构和算法12 之希尔排序
- ubuntu14.04截图工具ksnapsshot
- C++中的explicit关键字介绍
- Android 在界面中显示以及输入文本信息 TextView和EditText
- 如何做一名优秀的产品经理
- 基本数值类型转换
- Ubuntu下绑定静态arp,且重启不失效的方法
- 运维工程师的职责以及需要的品质
- 数组与指针的sizeof大小
- 【Redis源码剖析】 - Redis数据类型之列表List