Prime RingProblem素环问题(DFS)

Prime RingProblem素环问题(DFS)

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.

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

Source
Asia 1996, Shanghai (Mainland China)

本代码通俗易懂,来源https://blog.csdn.net/weixin_42173193/article/details/81514327

#include <cstdio>
#include <cmath>
#include<iostream>
using namespace std;
int nums[21] = {0};
int vis[21] = {0};
int n;
int sushu(int num)
{
	if (num == 1 || num == 0)
		return 0;
	for (int i = 2; i <= num / 2; i++)
	{
		if (num % i == 0)
			return 0;
	}
	return 1;
}
void dfs(int x)
{
	if (x == n + 1)
	{
		int j;
		for (j = 1; j < n; j++)
			printf("%d ", nums[j]);
		printf("%d", nums[j]);
		printf("\n");
		return;
	}
	for (int i = 1; i <= n; i++)
	{
		if (!vis[i]&&sushu(nums[x - 1] + i))
		{
			if (x == n)
			{
				if (!sushu(i + 1))
					continue;
			}
			nums[x] = i;
			vis[i] = 1;
			dfs(x + 1);
			vis[i] = 0;
		}
	}
}
int main()
{
	int cnt = 1;

	while (scanf("%d", &n) != EOF)
	{
		nums[1] = 1;
		vis[1] = 1;
		printf("Case %d:\n", cnt++);
		dfs(2);
		printf("\n");
	}

	return 0;
}

下面的方法来自老师,通过递归栈的方式,更加简洁。

#include <stdio.h>
#include <math.h>
int visit[21]={0};
int n,num[21]={0};

int prime(int k)
{    int i;
     for(i=2;i<=sqrt(k);i++)
           if(k%i==0) return 0;
     return 1;
}
void  DFS( int  k )
{   int i;
     if( k>n && prime(num[n]+num[1]) )
     {   printf("%d",num[1]);
          for(int i=2;i<=n;i++)    
               printf(" %d",num[i]);
          printf("\n");
      }
      else 
      {   for(i=2;i<=n;i++)  //第k步有n-1种可能
          { if( !visit[i] && prime(i+num[k-1]) )
	 {      visit[i]=1; 
	         num[k]=i;
                     DFS( k+1 ); 
                     visit[i]=0;
	 }
           }
       }            
  }
int main()
{     int cnt=1; 
      while(scanf("%d",&n)==1)
      {   if(n<1||n>19)	break;
          printf("Case %d:\n",cnt++);
          num[1]=1;     //第一个数一定为1 
          DFS(2);
          printf("\n");
       }
       return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值