• UVA 524


    Description

    Download as PDF
     

    A ring is composed of n (even number) circles as shown in diagram. Put natural numbers $1, 2, dots, 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 <= 16)

     

    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.

     

    You are to write a program that completes above process.

     

    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
    

     

    解题思路:如果这题用暴力枚举的话排列总数最高可高达16!=2*10^13,。就会超时。

    所以这用回溯。用一个数组来储存要输出的序列,判断条件就是如果目前的数加上他前面的数的和为素数并且没有这数没被标记。满足条件就加1递归并标记。直到走到递归边界(cur==n)。

     

     

    代码如下:

     

     

     

     

     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 int vis[50],isp[50],A[50],n;
     5 int is_prime(int x)    //用一个函数来判断是不是素数
     6 {
     7     for (int i = 2; i*i<= x ; i++)
     8         if (x% i == 0) return 0;
     9     return 1;
    10 }
    11 
    12 void dfs(int cur)
    13 {
    14     if(cur==n&&isp[A[0]+A[n-1]])   //判断到递归边界没有,并且不要忘了判断最后一个和第一个加起来是不是素数,因为它是一个圆。
    15     {
    16         for(int i=0; i<n-1; i++)
    17                 printf("%d ", A[i]);//按照题目格式输出,注意空格问题。(我TM栽在这一上午)
    18         printf("%d",A[n-1]);
    19         printf("
    ");
    20     }
    21     else
    22         for(int i=2; i<=n; i++)   //从2开始一个一个放
    23             if(!vis[i]&&isp[i+A[cur-1]])   //如果满足条件,和没有被标记
    24             {
    25                 A[cur]=i;    
    26                 vis[i]=1;    //标记
    27                 dfs(cur+1);    //递归
    28                 vis[i]=0;     //清除标记
    29             }
    30 }
    31 int main()
    32 {
    33     int m=0;
    34     while(scanf("%d",&n)==1&&n)
    35     {
    36         if(m>0)
    37             printf("
    ");
    38         ++m;
    39         for(int i=2; i<=n*2; i++)
    40             isp[i]=is_prime(i);
    41         printf("Case %d:
    ",m);
    42         //memset(vis,0,sizeof(vis));
    43         A[0]=1;   //A[0]一定为1
    44         dfs(1);    //从一开始递归
    45     }
    46     return 0;
    47 }

     

     


     
     
  • 相关阅读:
    对象进行比较
    java中length,length(),size()区别
    引用数据类型、自定义类
    java方法
    学员信息管理系统案例
    商品库存管理查看增减
    引用数据类型Scanner,Random
    Cantor表巧妙的做法
    UVA 11292 The dragon of Loowater勇士斗恶龙 11729 突击战 Commando War
    期末,祝不挂
  • 原文地址:https://www.cnblogs.com/huangguodong/p/4686215.html
Copyright © 2020-2023  润新知