素数环问题
2015-08-16 17:06
363 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1016
题意:给定一个整数,求其满足起点为1的素数环,,并把所有的素数环输出来。
类型:dfs+回溯
思路:因为起点为1,所以每次都从1开始进行深度优先搜索,设置一个数组ring,用来存放素数环的路径,当找到素数环的时候就打印环的路径。其中有一个剪枝的操作,如果给定的整数为奇数,那么肯定不存在素数环,(因为肯定存在两个奇数相邻,而奇数与奇数的和为偶数,所以一定不是素数环)所以不用进行搜索。做题的时候忘记写输入的数据以EOF结束,导致出现了Output Limit Exceeded这种错误。
时间复杂度:最坏的时间复杂度为O((n-1)!);
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#define N 50
using namespace std;
int visit
;//标记整数是否被访问
int ring
;//用来存放满足素数环的整数
int n;//素数环的大小
bool isprime(int k)//判断是否为素数,由于题目给定的范围很小,所以可以用这种直接的方法判断,不会超时
{
bool tag;
tag=true;
if(k==2)
return tag;
for(int j=2; j*j<=k; j++)
{
if(k%j==0)
{
tag=false;
break;
}
}
return tag;
}
void dfs(int l)
{
if(l==n&&isprime(ring[l]+ring[1]))//最后一次,跳出递归,输出素数环
{
for(int i=1;i<n;i++)
printf("%d ",ring[i]);
printf("%d\n",ring
);
return;
}
for(int j=2; j<=n; j++)//因为题目要求打印的素数环要按照字典序排列,所以从小到大遍历整数
if(!visit[j]&&isprime(ring[l]+j))//未被访问过,并且满足与上一次记录的整数之和为素数
{
visit[j]=1;//标记该整数已被访问
ring[l+1]=j;//更改记录整数,用作下一次素数环的判断
dfs(l+1);//递归实现,参数表示已经找到的满足素数环的整数的个数
visit[j]=0;//回溯,因为下一次可能要用到该整数。
}
}
int main()
{
int cased=1;
while(scanf("%d",&n)!=EOF)
{
memset(ring,0,sizeof(ring));//置0
memset(visit,0,sizeof(visit));//初始化为0
ring[1]=1;//第一个整数为1
printf("Case %d:\n",cased++);
if(n%2==0&&n>0)//剪枝,如果为奇数肯定没有素数环,只有偶数才可能有素数环
dfs(1);
printf("\n");
}
return 0;
}
题意:给定一个整数,求其满足起点为1的素数环,,并把所有的素数环输出来。
类型:dfs+回溯
思路:因为起点为1,所以每次都从1开始进行深度优先搜索,设置一个数组ring,用来存放素数环的路径,当找到素数环的时候就打印环的路径。其中有一个剪枝的操作,如果给定的整数为奇数,那么肯定不存在素数环,(因为肯定存在两个奇数相邻,而奇数与奇数的和为偶数,所以一定不是素数环)所以不用进行搜索。做题的时候忘记写输入的数据以EOF结束,导致出现了Output Limit Exceeded这种错误。
时间复杂度:最坏的时间复杂度为O((n-1)!);
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#define N 50
using namespace std;
int visit
;//标记整数是否被访问
int ring
;//用来存放满足素数环的整数
int n;//素数环的大小
bool isprime(int k)//判断是否为素数,由于题目给定的范围很小,所以可以用这种直接的方法判断,不会超时
{
bool tag;
tag=true;
if(k==2)
return tag;
for(int j=2; j*j<=k; j++)
{
if(k%j==0)
{
tag=false;
break;
}
}
return tag;
}
void dfs(int l)
{
if(l==n&&isprime(ring[l]+ring[1]))//最后一次,跳出递归,输出素数环
{
for(int i=1;i<n;i++)
printf("%d ",ring[i]);
printf("%d\n",ring
);
return;
}
for(int j=2; j<=n; j++)//因为题目要求打印的素数环要按照字典序排列,所以从小到大遍历整数
if(!visit[j]&&isprime(ring[l]+j))//未被访问过,并且满足与上一次记录的整数之和为素数
{
visit[j]=1;//标记该整数已被访问
ring[l+1]=j;//更改记录整数,用作下一次素数环的判断
dfs(l+1);//递归实现,参数表示已经找到的满足素数环的整数的个数
visit[j]=0;//回溯,因为下一次可能要用到该整数。
}
}
int main()
{
int cased=1;
while(scanf("%d",&n)!=EOF)
{
memset(ring,0,sizeof(ring));//置0
memset(visit,0,sizeof(visit));//初始化为0
ring[1]=1;//第一个整数为1
printf("Case %d:\n",cased++);
if(n%2==0&&n>0)//剪枝,如果为奇数肯定没有素数环,只有偶数才可能有素数环
dfs(1);
printf("\n");
}
return 0;
}
相关文章推荐
- scala 学习笔记(06) OOP(下)多重继承 及 AOP
- Scala数组小结
- Linux解压乱码
- POJ 1220 NUMBER BASE CONVERSION 高精度进制转换
- opentaps初学习之安装(mysql)
- Linux解压乱码
- (medium)LeetCode .Implement Trie (Prefix Tree)
- linux下I/O缓冲
- 如何增加你的气场
- [J2EE基础]初识JSP和Servlet
- 音乐播放器
- mysql锁研究系列二(MySQL表级锁的锁模式)
- uva_658_It's not a Bug, it's a Feature!(最短路)
- 机房收费系统验收小结(一)
- UVA - 10014 - Simple calculations (经典的数学推导题!!)
- 多线程与并发 概论
- 数据结构:大堆
- NoSQL架构实践(二)——以NoSQL为主
- Java功底篇系列-03-一些位运算符你会如何理解?
- nginx手记-命令