hdu 1016 Prime Ring Problem DFS

/**//*
2008-12-26 20:32:58 Accepted 1016 406MS 0K 846 B
一道简单的DFS搜索题
用数字绕成一个环,邻接的两个数之和是素数
给你一个数n,表示环里数字的个数(1,2,……,n),你的输出是所有可能的排列(从1开始计数)
我的思路是这样的:由于n的最大值是20(不大不小),我觉得这道题要用到打表什么的,先开一个数组记录素数
然后又是两个数之和是素数,于是开一个二维数组把对应两个数作为下标,值为0或1(是否为素数)。接着是“相
邻两个数”,我就觉得是通过前一个数找到配对的下一个数。这样就做成是深度优先搜索了。
*/
#include<iostream>
#define N 20
int pm[N*2],map[N][N];//pm记录素数,map记录两数之和是否为素数
int p[N],res[N];//p记录DFS搜索的路径,res记录输出结果
int used[N];//标记点是否已被搜索到
int n,ct=1;//n表示当前的数字总数,ct表示计数
void init()//初始化:包括把素数数组填好

{
pm[2]=pm[3]=pm[5]=pm[7]=pm[11]=pm[13]=pm[17]=pm[19]=pm[23]=pm[29]=pm[31]=pm[37]=1;//点不多,就枚举一下吧,点多了,就用伊拉托森筛选
for(int i=1;i<20;i++)
for(int j=1;j<20;j++)
if(i!=j && pm[i+j])
map[i][j]=1;//标记两数之和为素数的点
}
void output(int t)//输出例程

{
int k=0;
while(t)//通过对路径的分析获得结果
{
res[k++]=t;
t=p[t];
}
for(int j=n-1;j>=0;j--)//输出出来
{
if(j!=n-1)
putchar(' ');
printf("%d",res[j]);
}
putchar('\n');
}
void DFS(int t,int count)//深度优先搜索例程

{
used[t]=1;
if(count==n && map[t][1])
output(t);
for(int i=1;i<=n;i++)//遍历一下,然后回溯
if(map[t][i] && !used[i])
{
p[i]=t;
DFS(i,count+1);
used[i]=0;
}
}
int main()

{
init();
while(scanf("%d",&n)!=EOF)
{
printf("Case %d:\n",ct++);
DFS(1,1);
printf("\n");
}
return 0;
}
浙公网安备 33010602011771号