HDOJ(HDU).1016 Prime Ring Problem (DFS) [从零开始DFS(3)]

从零开始DFS

HDOJ.1342 Lotto [从零开始DFS(0)] — DFS思想与框架/双重DFS

HDOJ.1010 Tempter of the Bone [从零开始DFS(1)] —DFS四向搜索/奇偶剪枝

HDOJ(HDU).1015 Safecracker [从零开始DFS(2)] —DFS四向搜索变种

HDOJ(HDU).1016 Prime Ring Problem (DFS) [从零开始DFS(3)] —小结:做DFS题目的关注点

HDOJ(HDU).1035 Robot Motion [从零开始DFS(4)]—DFS题目练习

HDOJ(HDU).1241 Oil Deposits(DFS) [从零开始DFS(5)] —DFS八向搜索/双重for循环遍历

HDOJ(HDU).1258 Sum It Up (DFS) [从零开始DFS(6)] —DFS双重搜索/去重技巧

HDOJ(HDU).1045 Fire Net [从零开始DFS(7)]—DFS练习/check函数的思想

题意分析

给出数字n,要求将1-n的数字填成素数环,即相邻2个数字的和为素数,按字典序依次输出所有可能的组合。并且题目说过所有的组合开头均为1

哎呀这题太熟悉了,又是填数字的题目,似曾相识的感觉。

讨论过的填数字的题目,传送门:

HDOJ(HDU).1342 Lotto [从零开始DFS(0)]

HDOJ(HDU).1015 Safecracker [从零开始DFS(2)]

如果独立完成了几道dfs的题目,就会发现:其实dfs只是工具,真正考察思维的,是什么时候进行dfs,怎样进行dfs

1.什么时候进行dfs:即递归边界。满足何种情况就不进行搜索了,或者何种情况进行一个输出,亦或是利用条件判断去掉重复的情况。

2.怎样进行dfs:是二重搜索(HDOJ.1342),还是四向搜索(HDOJ.1010),还是在数组中找遍所有的元素(HDOJ.1015)。也许以后还有八向搜索,全部搜索等等方式。

不难发现本题要求的是,两个相邻的数字和为素数,那么也就是在每次搜索的时候,都判断一下前2个数字的和是否为素数,若是的话继续进行搜索,否则终止。

需要注意的是,最后还需要判断一下,最后一个数字和第一个数字的和是否为素数,因为题目的要求是素数环嘛。否则会出现多解。

为了方便判断素数,最好在初始化的时候进行素数筛。规模在50即可(n上限是19,最大就是19+18=37)。

上代码。

代码总览

/*
HDOJ.1016
Author:pengwill
Date:2017-2-5
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
bool visit[21],prime[51];
int b[21],n;
void init()
{
// prime 0 & not prime 1
for(int i = 2; i<=sqrt(50) ;++ i)
if(prime[i] == 0){
for(int j = 2;i*j<=50;++j)
prime[i*j] = 1;
}
prime[1] = 0; visit[1] = true;b[1] = 1;
}
bool check(int depth)
{
if(depth == n+1)//对于最后要判断首位数字的和是否为素数
if(prime[b[1]+b[depth-1]] == 0 && prime[b[depth-2]+b[depth-1]] == 0) return true;
else return false;
else if(prime[b[depth-2]+b[depth-1]] == 0) return true;//若不是最后就直接判断前2个即可
else return false;
}
void print()
{
for(int i = 1;i<=n; ++i)
if(i == 1) printf("%d",b[i]);
else printf(" %d",b[i]);
printf("\n");
}
void dfs(int depth)
{
if(false == check(depth)) return;
if(depth == n+1){
//输出
print();
return;
}
for(int i = 2; i<=n ;++i){
if(!visit[i]){
visit[i] = 1;
b[depth] = i;
dfs(depth+1);
visit[i] = 0;
}
}
}
int main()
{
int t = 1;
init();
while(scanf("%d",&n) != EOF){
printf("Case %d:\n",t++);
if(1==n) printf("1\n");
else dfs(2);//第一位是1,故从深度为2开始dfs
printf("\n");
}
return 0;
}

对n为1的时候进行特判。

init函数打50规模的素数表,然后把1置为访问过。若n不为1,对深度为2进行dfs。

每次在递归调用dfs之前,首先检查一下前边2个数的和(depth-1和depth-2)是否为素数。(因为b[0]为0,当depth为2的时候也可以直接调用check函数,不用特判)。需要注意的是,当depth为n+1的时候,check需要检查两项内容:一是刚才说的前两个数的和是否为素数,二是最后一个数和第一个数的和是否为素数。这样就能保证是素数环了。

本题还有一个坑点,就是输出格式。输出可能组合的时候注意是每个数字之间有一个空格,也就是在行末尾只有一个换行符。题目还说了在每种case之后输出个空行,也就是说不是每组数据之间(原文表述是 Print a blank line after each case. 是after,不是between)。 所以最后还是有一个空行的。

此题不难,dfs活学活用才是王道啊!!

HDOJ(HDU).1016 Prime Ring Problem (DFS)的更多相关文章

  1. HDU 1016 Prime Ring Problem (DFS)

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  2. [HDU 1016]--Prime Ring Problem(回溯)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1016 Prime Ring Problem Time Limit: 4000/2000 MS (Jav ...

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

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1016 Prime Ring Problem Time Limit: 4000/2000 MS (Jav ...

  4. HDU 1016 Prime Ring Problem(经典DFS+回溯)

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  5. Hdu 1016 Prime Ring Problem (素数环经典dfs)

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  6. hdu 1016 Prime Ring Problem(dfs)

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  7. hdu 1016 Prime Ring Problem(DFS)

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  8. HDU 1016 Prime Ring Problem (回溯法)

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  9. HDU - 1016 Prime Ring Problem 经典素数环

    Prime Ring Problem A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., ...

随机推荐

  1. JavaWeb——JavaWeb开发入门

    一.基本概念 1.1.WEB开发的相关知识 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. Internet上供外界访问的Web资源分为: 静态web资源( ...

  2. Android性能测试 | 启动时间篇

    [转载]原文地址:http://www.51testing.com/html/93/n-3724593.html 背景介绍 Android用户也许会经常碰到以下的问题: 1)应用后台开着,手机很快没电 ...

  3. hdu2147kiki's game(找规律)

    kiki's game Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 40000/10000 K (Java/Others)Total ...

  4. Qt-第一个QML程序-3-自定义一个按钮

    项目基本信息前两个已经说了,这里直接放下运行截图, 对的,这里就是说上面的那个红色的按钮,这里需要了解Qml的动画和状态 这里先把整个按钮的代码写出来,一点一点写 Rectangle { id:clo ...

  5. 使用 Fiddler工具模拟post四种请求数据

    post请求主体详解: 对于get请求来说没有请求主体entity-body.对于post请求而言,不会对发送请求的数据格式进行限制,理论上你可以发任意数据,但是服务器能不能处理就是另一回事了.服务器 ...

  6. 第一篇 HTML基础

    浏览网页,就是上网,上网的本质就是下载内容. 浏览器是个解释器,用来执行HTML.css.JS代码的. HTML,CSS, JavaScript 号称网络三剑客. 1. 浏览器发送一个域名给服务端 2 ...

  7. lintcode702 连接两个字符串中的不同字符

    连接两个字符串中的不同字符   给出两个字符串, 你需要修改第一个字符串,将所有与第二个字符串中相同的字符删除, 并且第二个字符串中不同的字符与第一个字符串的不同字符连接 思路:遍历两个字符串,找到互 ...

  8. 【转】cocos2d-x如何优化内存的应用

    原地址:http://cblog.chinadaily.com.cn/blog-942327-4327173.html 注:自身以前也写过cocos2d-x如何优化内存的应用,以及内存不够的情况下怎么 ...

  9. linux 命令行基础

    命令行基础 一些名词 「图形界面」 「命令行」 「终端」 「shell」 「bash」 安装使用 Windws: 安装git, 打开 gitbash Linux 打开终端 Mac 打开终端 基本命令 ...

  10. vmware安装64位系统“此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态”的问题

    虚拟机使用的是VMware Workstation,并且首次在虚拟机体验64 位系统.在新建好虚拟机,运行时候就出现了VMware Workstation 的提醒:此主机支持 Intel VT-x,但 ...