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. Visual Studio 2015 Test Explorer does not show anything

    Problem After install Visual Studio 2015 community and NUnit Test Adapter, I cannot find test cases ...

  2. jenkins--Jenkins+Git+coding+maven 实现自动化测试持续集成

    1.打开Jenkins官网,下载jenkins.war https://jenkins.io/download/ 2.将该war包直接放置到Tomcat的webapp下. 3.查看自己Tomcat的端 ...

  3. 腾讯云API弹性公网IP踩坑

    由于自己管理的云服务器数量比较多,时不时需要更换IP,在管理台上一下下点击,实在浪费时间,于是就想到了通过API调用的方式,将更换IP一系列动作,全部集成到Python代码里面,实现一行命令,完成IP ...

  4. Windows10系统,安装appium之坑

    本文主要讲述如何在 Windows10 系统上通过 npm 命令行安装 appium 应该有很多小伙伴在使用cnpm安装appium时遇到过各种报错,比如这样: 相信很多的小伙伴都会遇到这样的报错,导 ...

  5. Jenkins构建完成后实现自动将war包部署到指定服务器

    首先我们需要确定我们的jenkins安装了:publish over ssh 插件,如果没有安装,到-->jenkins首页-->系统管理-->插件管理-->可选安装里面去搜 ...

  6. HTML+JS = 网站注册界面源代码

    本注册页面未设置编码方式和兼容性,已测试,在Chrome浏览器显示正常 <!DOCTYPE html> <html> <head> <title>注册页 ...

  7. Internet History

    Alan Turing and Bletchley Park Top secret breaking effort(二战破译希特勒密码) 10,000 people at the peak(team ...

  8. 最长回文子串计算(fail)

    题意: 给定一个字符串s,在s中找到最长的回文子字符串.您可以假设s的最大长度为1000. 例子: 输入: “babad” 输出: “bab” 注: “aba”也是一个有效的答案. 我的答案: 想法: ...

  9. LintCode-4.丑数 II

    丑数 II 设计一个算法,找出只含素因子2,3,5 的第 n 大的数. 符合条件的数如:1, 2, 3, 4, 5, 6, 8, 9, 10, 12... 注意事项 我们可以认为1也是一个丑数 样例 ...

  10. sublime Text3 设置用新标签页打开新的文件

    今天用sublime Text3 打开项目文件,发现单击文件就可以打开,但是有一个问题:每次打开新文件就会覆盖当前的标签页,无法在新的标签页打开.于是在网上查了一下. 网上有人说在Preference ...