Prime Ring Problem
时间限制: 2000ms 内存限制: 32768KB HDU ID: 1016
题目描述
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.
Note: the number of first circle should always be 1.
输入
n (0 < n < 20).
输出
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.
You are to write a program that completes above process.
Print a blank line after each case.
样例输入
6 8
样例输出
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 2 3 ... n
解空间树思想求解,递归、回溯。相邻的每一个数都要求是素数,把第一数设定为 1 ,当然了是几都可以的,1有 n-1中选择,先从2开始往后选,符合条件放入a数组,由符合条件的这个数重复以上操作,直到最后一个确定出来则打印。
DFS深层理解:
原来对DFS的理解仅仅局限于图,现在发现这只是最基础的。DFS更多的表示的是一种状态,然后利用某中很简单的思维进行一次次的尝试,每次尝试成功了,就 深入一层递归进行下一次尝试,直到之后的尝试表明已经失败了不会成功,则回溯到这里。取消这次的尝试,去尝试其他的操作。简单地说,就是暴搜。只不过利用 了递归来实现尝试失败时的回溯,从而进行新的尝试。
代码:
#include <stdio.h> #include <math.h> bool use[21]; int a[21]; int n; bool isprime(int m) { int i; for(i = 2; i <= sqrt(m); i++) { if(m%i == 0) { return false; } } return true; } void init(int n) { int i; for(i=0; i < n; i++) { use[i] = false; } a[0] = 1;//让第一个数是1,因为是一个圆,是其他任何数都可以 } void dfs(int num)//搜索当前第num位置应该放的数字 { int i; if(num == n && isprime( 1 + a[n-1]))//最后一个位置的比较 { for(i=0;i<n;i++)//打印出来 { printf( i == n-1 ? "%d " : "%d ",a[i]); } } else { for( i = 2; i <= n; i++)//枚举每一个数 { if( isprime( i+a[num-1]) && !use[i] )//如果这个数符合和当前数成素数的条件并且没有使用过,就把它作为当前的下一个的相邻数 { a[num] = i;//a[]存的是满足条件的数 use[i] = true; dfs(num+1);//继续搜索下一个位置的数 use[i] = false;//回收重新使用 } } } } int main() { int t = 0; while(~scanf("%d",&n)) { printf("Case %d: ",++t); init(n); dfs(1); puts(""); } return 0; }