ZOJ 1457 Prime Ring Problem(dfs+剪枝)

时间:2024-10-30 10:07:56


Prime Ring Problem


Time Limit: 10 Seconds     
Memory Limit: 32768 KB

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.

ZOJ 1457 Prime Ring Problem(dfs+剪枝)

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



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

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath> using namespace std; int n,test=0;;
int cir[30];
int vis[30];
int prime[50]={0}; void dfs(int k)
{
if(k==n)
{
if(!prime[cir[k]+cir[1]])
return;
for(int i=1;i<n;i++)
printf("%d ",cir[i]);
printf("%d",cir[n]);
printf("\n");
return;
} for(int j=2;j<=n;j++)
{
if(!vis[j]&&prime[cir[k]+j]) //对于相邻素数的推断,在这里才干在zoj,AC,放最前面就仅仅能在HDU,AC了,一层递归调用的时间而已啊!
{ vis[j]=1;
cir[k+1]=j;
dfs(k+1);
vis[j]=0; //注意递归复原,这预计是最大的亮点了 } }
} int main()
{
prime[3]=1;
prime[5]=1;
prime[7]=1;
prime[11]=1;
prime[13]=1;
prime[17]=1;
prime[19]=1;
prime[23]=1;
prime[29]=1;
prime[31]=1;
prime[37]=1; while(scanf("%d",&n)!=EOF)
{
//memset(cir,0,sizeof cir);
//memset(vis,0,sizeof vis);
for(int i=1;i<=n;i++)
{
vis[i]=0;
}
printf("Case %d:\n",++test);
if(n % 2 == 1)
{
printf("\n");
continue;
} cir[1]=1;
dfs(1);
printf("\n");
} return 0;
}