题意:相邻两节点的值是素数,且是环形数据。
方法:用depth first search 方法,就可以得到答案了。
1)C语言
#include<iostream>
using namespace std;
/*
思路:给环顺序编号,例如:n=6,环看成链,数组下标值为1,2,3,4,5,6;
单词命名提示:
visit数组存放-1,1两个值,分别表示未访问,已访问
arr--array数组的意思,保存当前结点的值
*/
int visit[21],arr[21];
int n;
int main(){
void depthFirstSearch(int num);
int count = 0;
while(cin>>n){
fill(visit+1,visit+n+1,-1);// 整体数据右移一位
fill(arr+1,arr+n+1,1);// 整体数据右移一位
cout<<"Case "<<++count<<":"<<endl;// 数据提示行
visit[1] = 1;
depthFirstSearch(1);// 默认从第一个数据开始搜索
cout<<endl;// 输出空白行
}
return 0;
}
/*
传入一个参数,表示搜索num编号的圆圈,因为圆圈没有相对应的数组,所以传参
*/
void depthFirstSearch(int num){
bool isPrime(int n);
/*
要写鸿沟
*/
if(num==n&&isPrime(1+arr[num])){
/*
深搜到次,可以知道,答案了。
链表每一次对一个圆圈给值,如果满足就继续深搜,
不满足就回退,除非没有结果。
*/
for(int i=1;i<n;i++){
cout<<arr[i]<<" ";
}
cout<<arr[n]<<endl;
return;
}
/*
这是一个完全图的遍历
*/
for(int i=1;i<=n;i++){
/*
判断哪一个值没有被访问
*/
if(i!=num&&visit[i]!=1){
/*
父节点的值与孩子接点的值i之和,如果是素数,
那么就以该孩子进行搜索,依次类推。
*/
if(isPrime(i+arr[num])){
/*
1)标记当前圆圈已被遍历
2)搜索当前结点
3)回退,要修改成未被遍历
*/
visit[i] = 1;
arr[num+1] = i;
depthFirstSearch(num+1);
visit[i] = -1;
arr[num+1] = 1;
}
}
}
}
bool isPrime(int n){
if(n==2){
return true;
}
for(int i=2;i*i<=n;i++){
if(n%i==0){
return false;
}
}
return true;
}
java代码
import java.util.Scanner;
/*
* 思路:
* 把1-n之间的数放入环中,所有的数都必须放入,且没有重复的数字
* 这时使用depthFirstSearch法逐个放入,合格的数就放入,不合格的就回退。
*/
public class Main {
static int n;
/*
* visit用来判断第i个圆圈是否被遍历
* --1表示已被遍历,-1表示未被遍历,
* ring用来存储遍历序列
*/
static int visit[] = new int[21];
static int ring[] = new int[21];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int count = 1;
while (sc.hasNext()) {
// 输入数据
n = sc.nextInt();
// 初始化数据
for (int i = 1; i <= n; i++) {
visit[i] = -1;
ring[i] = 1;
}
// 处理数据,并输出结果
System.out.println("Case " + (count++) + ":");
visit[1] = 1;// 自己已被搜索
depthFirstSearch(1);
System.out.println();
}
}
/*
* num是用来告诉DFS搜索指定Num下标的圆圈值
*/
private static void depthFirstSearch(int num) {
/*
* 鸿沟
* 答案
*/
if (num == n && isPrime(ring[n] + ring[1])) {
for (int i = 1; i < n; i++) {
System.out.print(ring[i] + " ");
}
System.out.println(ring[n]);
return;
}
/*
* 这里应该用完全搜索
* 自己本身是不搜索
*/
for (int i = 1; i <= n; i++) {
/*
* 1)标记已被遍历
* 2)搜索下一个圆圈
* 3)擦掉标记
*/
if (i != num && visit[i] != 1) {
if (isPrime(i + ring[num])) {
visit[i] = 1;
ring[num + 1] = i;
depthFirstSearch(num + 1);
visit[i] = -1;
ring[num + 1] = 1;
}
}
}
}
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;
}
}
Prime Ring Problem
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 33927 Accepted Submission(s): 15019
Problem Description
A ring is compose of n circles as shown in diagram.
一个环由n个圆圈组成,如图所示。
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.
注意:圆圈的第一个数是1。
把自然数分别放到下面的圆圈中,每两个相邻的圆圈可以组合成一个素数。
Note: the number of first circle should always be 1.
注意:圆圈的第一个数是1。
Input
n (0 < n < 20).
输入的n小于20大于0。
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.
每一行代表一系列的圆圈号,分别从1到n,这里的输出是先顺序输出,然后逆序输出,其实用depth first search 就满足他的输出格式了。
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.
用下面格式输出结果。
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
Source
素数环问题求解

本文介绍了一种解决素数环问题的方法,通过深度优先搜索(Depth First Search, DFS)算法来寻找符合条件的素数环排列。素数环是由n个节点组成的环形结构,每个节点上放置1至n的自然数,相邻节点上的数字之和必须为素数。
426

被折叠的 条评论
为什么被折叠?



