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!!!!


  • 相关阅读:
    SmartDb代码修改
    windows下Nginx+RTMP部署
    嵌入式linux下获取flash分区大小
    (转)Qt添加windows开机自启动
    (转)交叉编译lrzsz
    关于海思SDK在Ubuntu下安装错误问题
    电总协议串口调试助手
    使用git将本地仓库上传到远程仓库(转)
    c++中包含string成员的结构体拷贝导致的double free问题
    59. 可变参数
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4359895.html
Copyright © 2011-2022 走看看