素数环 与 算法 全排列

在说起全排列前,先说一下昨天碰到的一个题目(答案不是我做出来的,但是我感觉有好多个亮点,贴出来方便日后的学习):

素数环

时间限制:1000 ms  |  内存限制:65535 KB

难度:2

描述

有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环。

为了简便起见,我们规定每个素数环都从1开始。例如,下图就是6的一个素数环。

输入
有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束。
输出
每组第一行输出对应的Case序号,从1开始。
如果存在满足题意叙述的素数环,从小到大输出。
否则输出No Answer。
样例输入
6
8
3
0
样例输出
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
Case 3:
No Answer

这个题的解法我考虑了很久,怎么说呢,感觉上并不是一道难度很大的题,实际操作起来却又无从下手。我说一下我的思考过程首先,这牵扯到寻找素数,但是呢,不是简单的找素数,而是两个数的和,在[1,n]之间的两个数m,n的和

        有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束。

这句话可以看出输入的n,最大,也就20.那么,即使在跑程序的时候,当真输入为20,最大的的一个和值也就是20+20=40,那么,我完全可以把[1,40]间的素数全部找出来并建立一个数组s[40],然后在[1,n]间查看,看哪两个数的和是素数,通过在数组s[40]里查找是否符合,若符合,将符合的值存放在一个数组里,而后输出。
#include <stdio.h>
#include<string.h>
int count,sa[40];    //  coount 用于控制输出流    sa[]是一个用来显示区间[2,42]内每个数是否为素数的数组,若为素数,其对应的sa[j]=1

/*** found 函数的定义,据作者说是由全排列改编过来的 ***/ 

void found(int n,int cur,int a[],int flag[]){  // 传入的 n 为 in[]数组中的元素,即输入值;  cur 初始值为1  是用于控制a[]的下标  ; a[]是一个a[0]=1的用于存放可满足数的数组;
                                              // flag[]是一个初始值全部置0的数组 , 用于储存在判定检查过程中的数是否为要用的值后的布尔值

    if(cur==n&&sa[a[0]+a[cur-1]])            // 这里用cur 与 输入值 n 进行比较判断  也就是说 a数组里存放的个数最多 n个,最多把[1,n]之间的值全部放进去,或者说数组a里的最大值肯定不能大于n
{
    {
        for(int i=0;i<n;i++)
            printf("%d ",a[i]);                //  那么,当a数组检查n是否可以存放时,这次遍历也就到此结束了,也就是该输出数组a了
        putchar(‘\n‘);
        count=0;
    }
}
/***** 在cur!=n时,需要进一步的检查时,利用递归,在区间[2,n],以此将满足的数存放在a[]中 *****/
    else                                                                                   //
        for(int i=2;i<=n;i++)                                                              //
        if(!flag[i]&&sa[i+a[cur-1]])                                                       //
        {                                                                               //
            a[cur]=i;                                                                  //
            flag[i]=1;                                                                //
            found(n,cur+1,a,flag);                                                   //
            flag[i]=0;                                                              //
        }                                                                          //
}                                                                                 //
/*********************************************************************************/
int main(void)
{
    int i=0,a[20],in[100],flag[20];   // in[20] 用于存放输入
    memset(sa,0,sizeof(sa));
    memset(flag,0,sizeof(flag));
/***********************************************************/
    for(int ok=1,k=2,j=2;j<40;j++,ok=1)                   //
    {                                                    //
        for(int i=2;i<=j/2;i++)                         //   在区间[2,40]里进行是否为素数的判定   用j控制数组sa的下标,同时,j还是一个数列【2,,40】
        {                                              //
            if(j%i==0)    ok=0;                       //  若为素数,sa[j]=1,否则不对sa[j]处理,即为0
        }                                            //
        if(ok) sa[j]=1;                             //
    }                                              //
/**************************************************/    

/**************************************/
    do                                  //    我很喜欢这段控制输入的代码
    {                                 //
        scanf("%d",&in[i++]);      //   很简单  但是很巧妙
    }while(in[i-1]);              //
/********************************///        大方  优雅
    a[0]=1;
    for(int j=1;j<i;j++)
    {
        count=1;
        printf("Case %d:\n",j);  // j 显示输入的数据的个数
        if(!(in[j-1]%2)||in[j-1]==1) found(in[j-1],1,a,flag);  // if里判定 in[]数组里的元素是否为奇数 或者是为1   两种情况均调用函数
        if(count)    printf("No Answer\n");
    }
    return 0;
}

先简单简单注释一下,可能在匆忙之中有一些错误,哪位有发现,多谢指出

时间: 2024-10-19 22:08:04

素数环 与 算法 全排列的相关文章

HDU 1016 Prime Ring Problem(素数环问题)

传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1016 Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 63806    Accepted Submission(s): 27457 Problem Description A ring is compos

素数环解题

<算法竞赛入门经典>这本书确实内容很丰富,但是对于初学者真的不怎么友善.主要的原因在于省略了太多的细节.为什么会有这样的情况呢?我个人是这样理解的,大多数人在给别人介绍一个知识点或者事物的时候,很容易将那些自己觉得比较简单或者基础的东西给省略掉.这种情况不是主观的,潜意识里就这么完成了.例如,我给一个人说,你看这瓶溶液是棕黄色的,至少不是硫酸铜.这里就有一个背景,硫酸铜溶液是蓝色的,我们为什么省略掉这个细节呢?因为我们潜意识里认为,别人也知道,而事实可能并非如此.回到这本书上来,有太多的内容也

nyoj 488 素数环(深搜)

素数环 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环. 为了简便起见,我们规定每个素数环都从1开始.例如,下图就是6的一个素数环. 输入 有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束. 输出 每组第一行输出对应的Case序号,从1开始. 如果存在满足题意叙述的素数环,从小到大输出. 否则输出No Answer. 样例输入 6 8 3 0 样

HDU2138 随机素数测试 Miller-Rabin算法

题目描述 Give you a lot of positive integers, just to find out how many prime numbers there are.. In each case, there is an integer N representing the number of integers to find. Each integer won’t exceed 32-bit signed integer, and each of them won’t be

HDU 1016 素数环(深搜)

Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 25134 Accepted Submission(s): 11222 Problem Description A ring is compose of n circles as shown in diagram. Put natural number 1,

素数环——搜索与回溯

题目描述 Description 从1到20这20个数摆成一个环,要求相邻的两个数的和是一个素数. 输入输出格式 Input/output 输入格式:无输入输出格式:一个整数(第几号素数环),一列数字(表示这个素数环) 输入输出样例 Sample input/output 样例测试点#1 输入样例: 无 输出样例: 这里就不演示了(…) 思路:代码很清楚,此处无需讲~~ 代码如下: 1 #include <stdio.h> 2 #include <math.h> 3 int a[3

UVA 524 素数环 【dfs/回溯法】

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

素数环 南阳acm488(回溯法)

素数环 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环. 为了简便起见,我们规定每个素数环都从1开始.例如,下图就是6的一个素数环. 输入 有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束. 输出 每组第一行输出对应的Case序号,从1开始. 如果存在满足题意叙述的素数环,从小到大输出. 否则输出No Answer. 样例输入 6 8 3 0 样

【DFS】素数环问题

题目: 输入正整数n,对1-n进行排列,使得相邻两个数之和均为素数,输出时从整数1开始,逆时针排列.同一个环应恰好输出一次.n<=16 如输入: 6 输出: 1 4 3 2 5 6 1 6 5 2 3 4 代码: 1 import java.util.Scanner; 2 3 public class 素数环 { 4 5 public static void main(String[] args) { 6 Scanner sc = new Scanner(System.in); 7 int n