zoukankan      html  css  js  c++  java
  • 南阳oj488--素数环(Dfs + 剪枝)

    素数环

    时间限制: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_丁国强

    这题hdoj上也有, 开始时候做这个题, 也没想那么多, 直接敲以前的代码, 一直Tle, 后来学会了一点新东西, 不会存在有奇数个元素的素数环(各元素相异)。但是 1 可以形成自环, 需特判。

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    int n, dis[20], vis[20];
    bool is_Prime(int a)
    {
        if(!a || a == 1)
            return false;
        if(a == 2 || a == 3)
            return true;
        for(int i = 2; i <= sqrt(a); i++)
            if(a % i == 0)
                return false;
        return true;
    }
    void Dfs(int a)
    {
        if(a == n && is_Prime(1+dis[n-1]))
        {
            for(int i = 0; i < n; i++)
                printf(i==0?"%d":" %d", dis[i]);
            printf(" ");
            return;    
        }    
        else
        {
            for(int i = 2; i <= n; i++)
            {
                if(!vis[i] && is_Prime(i+dis[a-1]))
                {
                    vis[i] = 1;
                    dis[a] = i;
                    Dfs(a + 1);
                    vis[i] = 0
                }
            }
        }

    int main()
    {
        int Q = 1
        while(~scanf("%d", &n), n)
        {
            printf("Case %d: ", Q++);
            if(n == 1){                //1需要特判。 
                printf("1 ");
                continue;
            }
            if(n&1){                //剪枝,有奇数(除1外)个不同元素的的素数环不存在。 
                printf("No Answer ");
                continue;
            }
            dis[0] = 1;
            memset(vis, 0sizeof(vis));
            Dfs(1);
        }
        return 0;
    }


     

  • 相关阅读:
    V4L2 soccamera 子系统
    ubuntu10.04 vim 配置
    Video for Linux Two
    I2C总线的仲裁机制
    Android Camera 通过V4L2与kernel driver的完整交互过程
    ubuntu安装辞典
    v4l2 camera 驱动架构 之 isp controller 驱动
    Android Camera 运行流程
    CentOS 7.x安装图文示范
    同余与模运算
  • 原文地址:https://www.cnblogs.com/soTired/p/4766016.html
Copyright © 2011-2022 走看看