hdu1016(Prime Ring Problem)

来源:互联网 发布:女士马丁靴品牌知乎 编辑:程序博客网 时间:2024/06/05 01:50

点击打开hdu1016

Problem Description

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

68
 

Sample Output

Case 1:1 4 3 2 5 61 6 5 2 3 4Case 2:1 2 3 8 5 6 7 41 2 5 8 3 4 7 61 4 7 6 5 8 3 21 6 7 4 3 8 5 2

题意:输入一个n,将1到n中各个数排成一个圆,要求相邻的两个数之和为素数(起始的数为1)。

解题思路:因为起始为1,所以首先用1去和其他数相加判断是否为素数,若是,则继续让这个与下一个没有用过的数进行相加,以此类推,不难看出这是一个搜索题型。然后将此转化为代码即可。

方法一:步骤详细,思路清楚,就是有点绕,但是理解起来还是比较容易的(只是在杭电里不能ac而已,java超时超内存原因)。

package search;import java.util.Scanner;public class SearchMethodDFS1 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while(sc.hasNext()){int n = sc.nextInt();int a[] = new int[n];//用来存储每个结点的值int color[] = new int[n];//颜色,搜索标志。-1---未搜索,1为已搜索int parent[] = new int[n];//用于记录每个元素的父结点//初始化for(int i=0;i<n;i++){a[i] = i+1;//结点的值color[i] = -1;parent[i] = -1;}int startNode=0;//搜索起始结点的下标int count=0;//相当于《算法导论》中的time,此处用于代表所搜的结点数,当结点数为n时则代表搜索完成dfs(a,color,parent,startNode,count);}}private static void dfs(int[] a, int[] color, int[] parent, int u, int count) {color[u] = 1;count++;//System.out.println(a[u]);//递归鸿沟if(count==a.length && isPrime(a[u]+a[0]) ){parent[0] = u;print(a,parent);return;}for(int v=0; v<a.length; v++){if(color[v]==-1 && isPrime(a[u]+a[v]) ){parent[v] = u;/*法1dfs(a,color,parent,v,count);//※※还原现场color[v] = -1;parent[v] = -1;*///法2 做数据备份,把备份数据传进递归搜索int color2[] = new int[a.length];int parent2[] = new int[a.length];for(int i=0;i<a.length;i++){color2[i] = color[i];parent2[i] = parent[i];}dfs(a,color2,parent2,v,count);}}}<span style="white-space:pre"></span>//输出最终结果private static void print(int[] a, int[] parent) {int index[] = new int[parent.length];int p=0;for(int i=0;i<parent.length;i++){//因为这种方法是记父节点形式记录结果的,所以结果需要倒序index[parent.length-1-i] = parent[p];p = parent[p];}for(int i=0;i<index.length;i++){if(i<index.length-1){System.out.print(a[index[i]]+" ");}else{System.out.println(a[index[i]]);}}}<span style="white-space:pre"></span>//判断是否为素数private static boolean isPrime(int n) {if(n==2){return true;}for(int i=2;i*i<=n;i++){if(n%i==0){return false;}}return true;}}

方法二(可以在杭电ac):这个就是直接将解题思路直接翻译过来的,即:先是1,然后找到与1相邻的符合条件的数放在s[]中,以此类推,直到找到最后一个数。(也就是依次求出相邻的数)

import java.util.Scanner;public class P1016 {private static int[] s;private static int[] visit;private static int sign,n;public static void main(String[] args) {Scanner sc=new Scanner(System.in);int k=1;while(sc.hasNext()){s=new int[20];s[1]=1;visit=new int[20];visit[1]=1;n=sc.nextInt();System.out.println("Case "+k+":");k++;DFS(2);System.out.println();}}private static void DFS(int x) {if(x>n&&isPriem(s[x-1]+1)){print(s);}for(int i=2;i<=n;i++){if(visit[i]==0&&isPriem(s[x-1]+i)){s[x]=i;visit[i]=1;DFS(x+1);visit[i]=0;}}}private static void print(int[] s2) {//输出结果for(int i=1;i<n;i++){System.out.print(s2[i]+" ");}System.out.println(s2[n]);}private static boolean isPriem(int x) {//判断是否为素数if(x==2){return true;}for(int i=2;i*i<=x;i++){if(x%i==0){return false;}}return true;}}

方法三:面向对象方法

package search;import java.util.Scanner;public class SearchMethodDFS2 {public static boolean isPrime(int n){if(n==2)return true;for(int i=2;i*i<=n;i++){if(n%i==0){return false;}}return true;}public static void main(String[] args) {Scanner sc = new Scanner(System.in);while(sc.hasNext()){int n = sc.nextInt();//初始化图Node nodes[] = new Node[n];for(int i=0;i<nodes.length;i++){nodes[i] = new Node(i+1,-1,null);}int startNum=0;int count=0;//计数dfs(nodes,startNum,count);}}private static void dfs(Node[] nodes, int u, int count) {count++;nodes[u].color=1;//鸿沟if(count==nodes.length && isPrime(nodes[u].value+nodes[0].value) ){print(nodes,u);}for(int v=1;v<nodes.length;v++){if(nodes[v].color==-1 && isPrime(nodes[u].value+nodes[v].value)){nodes[v].parent = nodes[u];dfs(nodes,v,count);nodes[v].color=-1;nodes[v].parent=null;}}}private static void print(Node[] nodes, int u) {Node nodes2[] = new Node[nodes.length];Node node = nodes[u];for(int i=nodes.length-1; i>=0; i--){nodes2[i] = node;node = node.parent;}int i=0;for(;i<nodes.length-1;i++){System.out.print(nodes2[i].value+" ");}System.out.println(nodes2[i].value);}}class Node{int value;int color;Node parent;public Node(int value, int color, Node parent) {this.value = value;this.color = color;this.parent = parent;}}











2 0
原创粉丝点击