Problem 1010 - 素数环问题
Problem 1010 - 素数环问题
Time Limit: 1000MS Memory Limit: 65536KB Difficulty:
Total Submit: 473 Accepted: 93 Special Judge: No
Description
有一个由n个数字相连组成的圆环(n<20),组成圆环的数字分别为1,2,3...n-1,n.要求每两个相邻元素的和为素数。(注意:第一个元素始终为1)。
Input
n (0<n<20)
Output
要求输出所有符合条件的组成圆环的元素,每个符合条件的圆环按顺时针或者逆时针将元素依次输出,输出格式见样例。要求按字典序输出。
每例以空行分开。
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
Hint
Source
Wang Miao
分析Time Limit: 1000MS Memory Limit: 65536KB Difficulty:
Total Submit: 473 Accepted: 93 Special Judge: No
Description
有一个由n个数字相连组成的圆环(n<20),组成圆环的数字分别为1,2,3...n-1,n.要求每两个相邻元素的和为素数。(注意:第一个元素始终为1)。
Input
n (0<n<20)
Output
要求输出所有符合条件的组成圆环的元素,每个符合条件的圆环按顺时针或者逆时针将元素依次输出,输出格式见样例。要求按字典序输出。
每例以空行分开。
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
Hint
Source
Wang Miao
素数环,将1到N的整数排成一圈,使相邻两个数之和为素数。
根据定义对由1到N的整数序列进行深度优先遍历即可。
当遍历到某一个值已经不满足要求可以直接回溯,所以不需要遍历所有状态空间,速度还是很不错的。
根据题目的意思,它给的N值都是可以构成素数环的。但并不是任意的N都可以构成素数环。
比如当N是大于1的奇数时就构不成素数环。为什么?
根据抽屉原理,如果N为奇数(大于1)那么围成一圈后必然有两个不相等的奇数相邻,而两个不相等的奇数的和绝不会是素数。
另外,由于在搜索过程中需要进行大量的素数判断,且题目中N的取值范围不大,所以先准备一张素数表可以减少重复计算提高效率。素数筛在这里应用很合适。
根据定义对由1到N的整数序列进行深度优先遍历即可。
当遍历到某一个值已经不满足要求可以直接回溯,所以不需要遍历所有状态空间,速度还是很不错的。
根据题目的意思,它给的N值都是可以构成素数环的。但并不是任意的N都可以构成素数环。
比如当N是大于1的奇数时就构不成素数环。为什么?
根据抽屉原理,如果N为奇数(大于1)那么围成一圈后必然有两个不相等的奇数相邻,而两个不相等的奇数的和绝不会是素数。
另外,由于在搜索过程中需要进行大量的素数判断,且题目中N的取值范围不大,所以先准备一张素数表可以减少重复计算提高效率。素数筛在这里应用很合适。
程序代码:
#include<stdio.h> char np[40]; void ring(int n, int d) { static int r[20], f[21]; int i, t; if(d == n) { if(np[r[n - 1] + 1]) return; for(putchar('1'), i = 1; i < n; printf(" %d", r[i++])); puts(""); return; } if(!d) { for(i = 0; i < n; f[i] = 0, r[i++] = i + 1); ring(n, d + 1); } else for(i = 2; i <= n; i++) { if(f[i] || np[i + r[d - 1]]) continue; r[d] = i; f[i] = 1; ring(n, d + 1); f[i] = 0; } } int main() { int i, j; for(i = 2; i < 40; i++) if(!np[i]) for(j = i + i; j < 40; j += i) np[j] = 1; for(i = 1; scanf("%d", &j) != EOF; i++) { if(i - 1) puts(""); printf("Case %d:\n", i); ring(j, 0); } return 0; }
重剑无锋,大巧不工