zoukankan      html  css  js  c++  java
  • 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 }

     

     


     
     
  • 相关阅读:
    链表--判断一个链表是否为回文结构
    矩阵--“之”字形打印矩阵
    二叉树——平衡二叉树,二叉搜索树,完全二叉树
    链表--反转单向和双向链表
    codeforces 490C. Hacking Cypher 解题报告
    codeforces 490B.Queue 解题报告
    BestCoder19 1001.Alexandra and Prime Numbers(hdu 5108) 解题报告
    codeforces 488A. Giga Tower 解题报告
    codeforces 489C.Given Length and Sum of Digits... 解题报告
    codeforces 489B. BerSU Ball 解题报告
  • 原文地址:https://www.cnblogs.com/huangguodong/p/4686215.html
Copyright © 2011-2022 走看看