【HDU 1016】Prime Ring Problem(DFS、素数筛)
来源:互联网 发布:linux cp 合并文件夹 编辑:程序博客网 时间:2024/05/16 07:49
Prime Ring Problem
A ring is compose of n circles as shown in diagram. Put natural number 1, 2, …, n into each circle separately, and the sum of numbers in two adjacent circles should be a prime.
Note: the number of first circle should always be 1.
Input
n (0 < n < 20).
Output
The output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above requirements. Print solutions in lexicographical order.
You are to write a program that completes above process.
Print a blank line after each case.
Sample Input
6
8
Sample Output
Case 1:
1 4 3 2 5 6
1 6 5 2 3 4
Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2
题意
已知一个数n,将数字1~n围成一个圆环,要求: 相邻两个数之和为素数。
输出:
- 数字的方向一致(同顺时针或同逆时针),并保证排列不重复
- 只有一个数(n==1)时,输出1
- 输出Case k:(k为数据组数),每一组输出(第一个除外)之前都有一个空行
思路:
- 要求每两个相邻数之和都为素数,那么只要每次递归调用DFS时判断之前两个数之和是否为素数,另外注意因为是一个环,最后还要判断一下最后一个数和第一个数之和是否为素数。
- 程序开始时求出一个素数数组,只需求出50以内的素数即可,因为数据<20,最大的素数和为17+19=36。此处用的是素数筛法(什么是素数筛法?)求素数。
素数筛法概览:
- 把从1开始的、某一范围内的正整数从小到大顺序排列, 1不是素数,首先把它筛掉。剩下的数中选择最小的数是素数,然后去掉它的倍数。依次类推,直到筛子为空时结束
- 例如: 先把n个自然数按次序排列起来。1不是质数,也不是合数,要划去。第二个数2是质数留下来,而把2后面所有能被2整除的数都划去。2后面第一个没划去的数是3,把3留下,再把3后面所有能被3整除的数都划去。3后面第一个没划去的数是5,把5留下,再把5后面所有能被5整除的数都划去。这样一直做下去,就会把不超过N的全部合数都筛掉,留下的就是不超过N的全部质数
代码示例:
#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#define MAX 51using namespace std;int prime[MAX];//素数数组 bool vis[21]; //访问数组 int n;// 个数 int ans[21];//解答输出数组 void Prime_set() //筛法求素数 { //Isprime 0、 IsNotprime 1 for(int i = 2; i<=sqrt(MAX) ;++ i) if(prime[i] == 0){ for(int j = 2;i*j<=MAX;++j) prime[i*j] = 1; } prime[1] = 0,vis[1]=true;//1虽然不是素数,但在此假设为0,将vis[1]设为true即不会遍历到1 }void DFS(int depth){ if(prime[ans[depth-1]+ans[depth-2]]!=0) return ; //前两个数之和不是素数退出 if(depth==n+1&&prime[ans[depth-1]+ans[1]]!=0) return ; //当选到最后一个数时,第一个数和最后一个数之和不是素数时退出 if(depth==n+1) //选到最后一个数,输出 { for(int i=1;i<=n;i++) { if(i==1) cout<<ans[i]; else cout<<" "<<ans[i]; } cout<<endl; } for(int i=2;i<=n;i++) //把1~n按照一定顺序(DFS求得)填入数组ans { if(!vis[i]) { vis[i]=true; ans[depth]=i; DFS(depth+1); vis[i]=false; } }}int main(){ int t=1; Prime_set(); while(cin>>n) { cout<<"Case "<<t++<<":"<<endl; memset(vis,false,sizeof(vis)); ans[1] = 1;//1永远是首元素 if(n==1) cout<<"1"<<endl; else DFS(2);//1永远是首元素,从2开始DFS ;也防止之后depth-2<0 cout<<endl; } return 0;}
注:- Q:1不是素数,为何要prime[1] = 0?
- A:1虽然不是素数,但在此假设为0。因为之后判断(判断两个相邻素数和的时候)会出现一些问题:
if(prime[ans[depth-1]+ans[depth-2]]!=0)
在主函数初始进入DFS(2)时,这一句之中的depth-2等于0,ans[0]不在讨论范围之中,故仍然为0,而ans[1]为1,ans[depth-1]+ans[depth-2]=1,prime[1]如果不等于0的话,将会直接return。
- A:1虽然不是素数,但在此假设为0。因为之后判断(判断两个相邻素数和的时候)会出现一些问题:
- 【HDU 1016】Prime Ring Problem(DFS、素数筛)
- hdu 1016 Prime Ring problem(dfs 素数环)
- Hdu 1016 Prime Ring Problem (素数环经典dfs)
- HDU 1016 Prime Ring Problem(DFS回溯+素数判断)
- hdu-1016 Prime Ring Problem(素数环 dfs)
- HDU 1016 Prime Ring Problem(DFS 素数环问题)
- hdu-1016Prime Ring Problem(素数环 dfs)
- hdu-1016 Prime Ring Problem(素数环) DFS解法
- hdu 1016 Prime Ring Problem(dfs,素数环)
- HDU (dfs)1016 Prime Ring Problem素数环
- hdu 1016Prime Ring Problem dfs经典题 素数环
- dfs hdu 1016 Prime Ring Problem 素数环
- HDU 1016 Prime Ring Problem (素数环)(DFS)
- HDU 1016 Prime Ring Problem 素数环
- hdu 1016 Prime Ring Problem (素数环)
- hdu 1016 Prime Ring Problem 素数环
- Prime Ring Problem hdu 1016 dfs
- Hdu-1016 Prime Ring Problem【DFS】
- 237. Delete Node in a Linked List
- MySQL创建普通用户
- Java之异常
- Linux C 多线程编程 互斥锁
- 杭电acm 1171Big Event in HDU(0-1背包)
- 【HDU 1016】Prime Ring Problem(DFS、素数筛)
- 2017云哥性能测试实战带你走出迷茫
- Java并发集合操作中对锁的应用
- Python学习之文件处理详解
- Java表格仿mysql实现基本操作(连接,分组排序,统计等)
- Linux C 多线程编程条件变量
- [第五季]14.属性选择器和伪类伪元素
- 美团js面试题
- 下一阶段的一些想法