zoukankan      html  css  js  c++  java
  • nyist 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
    例子输出
    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
    来源
    hdu改编
    上传者
    ACM_丁国强
    这道题应该算是比較简单的题了,提交了好几次都是TLE,我就郁闷了。。。看来基础还是不扎实啊。。。最后用素数的哈希表最终AC了。。。先前是各种TLE,程序优化真的非常重要啊。这就是算法的魅力所在~
    #include <stdio.h>
    #include <string.h>
    #define MAXN 40
    int A[MAXN];
    int vis[MAXN];
    int n;
    int isprime[40]={
    0,0,1,1,0,1,0,1,0,0,
    0,1,0,1,0,0,0,1,0,1,
    0,0,0,1,0,0,0,0,0,1,
    0,1,0,0,0,0,0,1,0,0,
    };//素数的哈希表,1代表就是素数
    void dfs(int cur)//搜索+回溯(回溯事实上也是依据树的深度搜索来的)
    {
        int i;
        if(cur==n && isprime[A[0]+A[n-1]])//递归边界,对第一个和最后一个数进行測试
        {
            for(i=0;i<n;i++)
                printf("%d ",A[i]);
            printf("
    ");
        }
        else for(i=2;i<=n;i++)//尝试放置每个数
        if(!vis[i] && isprime[i+A[cur-1]])//先看这个数有没有被标记,然后看与前面的一个数的和是否为素数
        {
            A[cur]=i;
            vis[i]=1;//标记搜索过的路径
            dfs(cur+1);
            vis[i]=0;//清除标记 ,回溯
        }
    }
    int main()
    {
       int i,j;
       int k=1;
       while(scanf("%d",&n)&&n!=0)
       {
           memset(vis,0,sizeof(vis));//初始化vis数组
           for(i=0;i<n;i++)
             A[i]=i+1; 
           printf("Case %d:
    ",k++);
           if(n==1)//自成环
           {
               printf("1
    ");
               continue;
           }
           if(n%2!=0)//剪枝,假设n为奇数不可能成环
           {
               printf("No Answer
    ");
               continue;
           }
    	  dfs(1);
       }
        return 0;
    }

    这里我应该还是钻了空子,还是不太严谨,20一类的偶数都可以成素数环,大于20就不一定了,还是有待改进啊。。

    本来是想用筛选发筛选出素数的,各种TLE啊。。。大哭 (感觉筛选法效率挺高的啊)

     for(i=2;i<=MAXN;i++)
           {
           	   isprime[0]=isprime[1]=1;
               if(isprime[i]==0)
                for(j=i+i;j<MAXN ;j+=i)
                  isprime[j]=1;
           }
    还是应该多学习别人的优秀算法,学无止境啊。 多学习别人的经验奋斗,keep moving!!!!


  • 相关阅读:
    OpenCV——PS 图层混合算法(一)
    PS 滤镜算法原理——照亮边缘
    PS 色调——老照片效果
    PS 滤镜算法原理——浮雕效果
    PS 滤镜算法原理——碎片效果
    PS 滤镜算法原理——染色玻璃
    PS 滤镜算法原理——高反差保留 (High Pass)
    PS图像特效算法——镜像渐隐
    手把手教你写专利申请书/怎样申请专利
    经常使用的webservice接口
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4359895.html
Copyright © 2011-2022 走看看