hdu 1016 Prime Ring Problem dfs

来源:互联网 发布:stl queue 源码 编辑:程序博客网 时间:2024/05/08 07:38

题意:给定一个数n,将1~n共n个数组成一个环,使得环上,任意先连得两个数之和为素数。输出所有符合条件的环。

题解:

先预处理出所有两两之和为素数的数对。然后通过dfs枚举下一个数,直到完成环,还需要判断下结尾和开头是否符合条件。



代码:

#include <cstdio>#include <cstring>#include <cmath>#include <string>#include <queue>#include <iostream>#include <algorithm>using namespace std;#define LL __int64const int maxn=40;int n;int prime[maxn],t;int vis[maxn],g[maxn],f[maxn][maxn];vector<int>e[maxn];void init()//预处理出1~20中的数其能两两相加为素数的对。{    memset(vis,0,sizeof(vis));    memset(f,0,sizeof(f));    int i,j,k;    //找出所有40以内的素数    for(i=2;i<40;i++)    {        if(!vis[i])prime[t++]=i;        for(j=i*i;j<40;j+=i)            vis[j]=1;    }    //找出每个数符合条件的对应数。    for(i=1;i<20;i++)    {        for(j=0;j<t;j++)        {            if(prime[j]-i<=0)continue;            if(prime[j]-i>=20)break;            e[i].push_back(prime[j]-i);            f[i][prime[j]-i]=1;        }    }}void dfs(int pre,int num){    int i,u;    if(num==n)    {        if(!f[1][g[n-1]])return;//结尾还要判断下        printf("%d",g[0]);        for(i=1;i<n;i++)            printf(" %d",g[i]);        printf("\n");        return ;    }    for(i=0;i<e[pre].size();i++)    {        u=e[pre][i];        if(u>n)break;        if(vis[u])continue;        vis[u]=1;        g[num]=u;        dfs(u,num+1);        vis[u]=0;    }}int main(){    init();    int tt=0;    while(scanf("%d",&n)!=EOF)    {        printf("Case %d:\n",++tt);        memset(vis,0,sizeof(vis));        g[0]=1;        vis[1]=1;        dfs(1,1);        printf("\n");    }    return 0;}


0 0
原创粉丝点击