人生第一个深入理解的DFS题 HDU 1016
2016-12-24 14:39
204 查看
A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each circle separately, and the sum of numbers in two adjacent circles should be a prime.
Note: the number of first circle should always be 1. 翻译: 环是由n个圆圈组成的,如图所示。将自然数1、2、n、n分别放入每个圆中,两个相邻圆的个数之和应为素数。 注:第一圈的数目应始终为1。
![](https://odzkskevi.qnssl.com/427b1dd2282412709d583cc17eda983e?v=1482199372)
Inputn (0 < n < 20).
OutputThe output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above requirements. Print solutions in lexicographical order.
You are to write a program that completes above process.
Print a blank line after each case. 翻译:输出格式显示为下面的示例。每一行代表在环圈数从1开始顺时针和anticlockwisely系列。数字的顺序必须满足上述要求。在字典顺序打印解决方案。 您要编写一个程序,完成上述过程。 在每一种情况下打印一条空白线。
Sample Input
Sample Output
#include <stdio.h>
#include <string.h>
int n,prime[50],a[50],vis[50];//a[]数组用来存储每一次适合题意的一组数据 vis[]在dfs中用来判断数字是否在之前的dfs中使用过了
void isprime()
{
int i,j;
for(i = 2;i<50;i++)
prime[i] = 1;
prime[0] = prime[1] = 0;
for(i = 2;i<50;i++)
{
if(prime[i])
for(j = i+i;j<50;j+=i)
prime[j] = 0;//prime[x]数组中x为质数时为1,否则为0.
}
}void dfs(int step)//step代表第几个环
{
int i,j;
if(step == n+1 && prime[a
+a[1]])//结束条件
{
for(i = 1;i<n;i++)
printf("%d ",a[i]);
printf("%d\n",a
);
return 0;
}
for(i = 2;i<=n;i++)//每一步dfs搜索都需要把这个节点可能的情况搜索一遍
if(!vis[i] && prime[i+a[step-1]])//此数未用并且与上一个放到环中的数相加是素数
{
a[step] = i;
vis[i] = 1;
dfs(step+1);
vis[i] = 0;//将vis[i]清零预备下一次搜索时判断i有没有被使用过
}}int main()
{ int cas = 1;
a[1] = 1;
isprime();
while(scanf("%d",&n))
{
printf("Case %d:\n",cas++);
dfs(2);
printf("\n");
} return 0;
}
下面是个运行时间更短的方法 很不错的程序
#include <stdio.h>
int num[21],mark[21],n;
int prime_num[12] = {2,3,5,7,11,13,17,19,23,29,31,37};
//判断是否是质数,是返回1,不是返回0
int is_prime(int a)
{
int i;
for( i = 0; i < 12;i++)
if(a==prime_num[i])return 1;
return 0;
}
void print_num()
{int i;
for( i = 1; i < n;i++)
printf("%d ",num[i]);
printf("%d",num
);
}
int dfs(int post,int pre,int flag)
{
int i;
//如果不符合,直接返回
if(!is_prime(pre+post))
return ;
num[flag] = pre;
if(flag==n&&is_prime(pre+1))
{
print_num();
printf("\n");
}
//使用过了这个数字就标记为0
mark[pre] = 0;
for( i = 2;i<=n;i++)
if(mark[i]!=0)dfs(pre,i,flag+1);
//标记位恢复原状
mark[pre] = 1;
}
int main()
{
int count,i;
count = 1;
while(scanf("%d",&n)!=EOF)
{
for( i = 1; i <= n; i++)
mark[i] = 1;
num[1] = 1;
printf("Case %d:\n",count++);
if(n==1)printf("1\n");
for(i = 2;i<=n;i++)
dfs(1,i,2);
printf("\n");
}
return 0;
}
Note: the number of first circle should always be 1. 翻译: 环是由n个圆圈组成的,如图所示。将自然数1、2、n、n分别放入每个圆中,两个相邻圆的个数之和应为素数。 注:第一圈的数目应始终为1。
Inputn (0 < n < 20).
OutputThe output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above requirements. Print solutions in lexicographical order.
You are to write a program that completes above process.
Print a blank line after each case. 翻译:输出格式显示为下面的示例。每一行代表在环圈数从1开始顺时针和anticlockwisely系列。数字的顺序必须满足上述要求。在字典顺序打印解决方案。 您要编写一个程序,完成上述过程。 在每一种情况下打印一条空白线。
Sample Input
6 8
Sample Output
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
代码如下
#include <stdio.h>
#include <string.h>
int n,prime[50],a[50],vis[50];//a[]数组用来存储每一次适合题意的一组数据 vis[]在dfs中用来判断数字是否在之前的dfs中使用过了
void isprime()
{
int i,j;
for(i = 2;i<50;i++)
prime[i] = 1;
prime[0] = prime[1] = 0;
for(i = 2;i<50;i++)
{
if(prime[i])
for(j = i+i;j<50;j+=i)
prime[j] = 0;//prime[x]数组中x为质数时为1,否则为0.
}
}void dfs(int step)//step代表第几个环
{
int i,j;
if(step == n+1 && prime[a
+a[1]])//结束条件
{
for(i = 1;i<n;i++)
printf("%d ",a[i]);
printf("%d\n",a
);
return 0;
}
for(i = 2;i<=n;i++)//每一步dfs搜索都需要把这个节点可能的情况搜索一遍
if(!vis[i] && prime[i+a[step-1]])//此数未用并且与上一个放到环中的数相加是素数
{
a[step] = i;
vis[i] = 1;
dfs(step+1);
vis[i] = 0;//将vis[i]清零预备下一次搜索时判断i有没有被使用过
}}int main()
{ int cas = 1;
a[1] = 1;
isprime();
while(scanf("%d",&n))
{
printf("Case %d:\n",cas++);
dfs(2);
printf("\n");
} return 0;
}
下面是个运行时间更短的方法 很不错的程序
#include <stdio.h>
int num[21],mark[21],n;
int prime_num[12] = {2,3,5,7,11,13,17,19,23,29,31,37};
//判断是否是质数,是返回1,不是返回0
int is_prime(int a)
{
int i;
for( i = 0; i < 12;i++)
if(a==prime_num[i])return 1;
return 0;
}
void print_num()
{int i;
for( i = 1; i < n;i++)
printf("%d ",num[i]);
printf("%d",num
);
}
int dfs(int post,int pre,int flag)
{
int i;
//如果不符合,直接返回
if(!is_prime(pre+post))
return ;
num[flag] = pre;
if(flag==n&&is_prime(pre+1))
{
print_num();
printf("\n");
}
//使用过了这个数字就标记为0
mark[pre] = 0;
for( i = 2;i<=n;i++)
if(mark[i]!=0)dfs(pre,i,flag+1);
//标记位恢复原状
mark[pre] = 1;
}
int main()
{
int count,i;
count = 1;
while(scanf("%d",&n)!=EOF)
{
for( i = 1; i <= n; i++)
mark[i] = 1;
num[1] = 1;
printf("Case %d:\n",count++);
if(n==1)printf("1\n");
for(i = 2;i<=n;i++)
dfs(1,i,2);
printf("\n");
}
return 0;
}
相关文章推荐
- HDU 1016 Prime Ring Problem(DFS)
- HDU 1010题解这是一道简单的DFS加回溯题,看懂后就会对递归和回溯有较深刻的理解。
- HDU - 1016 Prime Ring Problem DFS
- HDU 1016 Prime Ring Problem (DFS回溯)
- 【HDU 1016】Prime Ring Problem(DFS)
- HDU 1016 Prime Ring Problem(dfs)
- HDU1016.....dfs和&&的短路作用
- [ACM] hdu 1016 Prime Ring Problem (DFS)
- HDU 1016 - Prime Ring Problem (DFS)
- HDU 1016--DFS第一炮
- HDU 1016 Prime Ring Problem(DFS)
- hdu 1016 DFS
- HDU-1016-Prime Ring Problem( C && 经典DFS题 )
- hdu 1016 Prime Ring Problem(DFS)
- HDU 1016 DFS
- hdu 1016(dfs+dp)
- HDU 1016 Prime Ring Problem (DFS)
- [ACM] hdu 1016 Prime Ring Problem (DFS)
- hdu 4034 Graph (floyd的深入理解)
- (step 4.3.3)hdu 1016(Prime Ring Problem——DFS)