HDU 1016 Prime Ring Problem (回溯法)
Prime Ring Problem
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 34846 Accepted Submission(s): 15441
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.
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.
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
题意:在1到n构成一个圆环两两相邻的数和为素数,输出所有情况。
思路:感觉搜索最重要的就是找状态,这里的状态就是(当前这个数,已经放置了的个数)。
收获:回溯法:因为有可能再次使用一个数,所以回溯。
#include <cstdio> #include <iostream> #include <cstdlib> #include <algorithm> #include <ctime> #include <cmath> #include <string> #include <cstring> #include <stack> #include <queue> #include <list> #include <vector> #include <map> #include <set> using namespace std; const int INF=0x3f3f3f3f; const double eps=1e-10; const double PI=acos(-1.0); #define maxn 500 int n; int vis[maxn]; int a[maxn]; int judge(int x) { if(x <= 1) return 0; int m = floor(sqrt(x) + 0.5); for(int i = 2; i <= m; i++) if(x%i == 0) return 0; return 1; } void dfs(int pos, int num) { a[num] = pos; if(num == n && judge(pos+1)) { for(int j = 1; j <= n-1; j++) printf("%d ", a[j]); printf("%d\n", a[n]); return; } for(int i = 2; i <= n; i++) { int sum = pos + i; if(judge(sum) && !vis[i]) { vis[i] = 1; dfs(i, num+1); vis[i] = 0; } } } int main() { int cas = 1; while(~scanf("%d", &n)) { flag = 1; memset(vis, 0, sizeof vis); printf("Case %d:\n", cas++); dfs(1, 1); puts(""); } return 0; }