杭电acm1016 Prime Ring Problem

来源:互联网 发布:怎么看linux的ip地址 编辑:程序博客网 时间:2024/06/05 03:06
/*
dfs(深度优先搜索->“一搜到底”):
  此题是要求从1~n组成一个环且每相邻的两个数相加为素数 注意题中说明每次都是从1开始
  要定义两个数组:一个vis[]数组用来标记1~n的数是否被使用,还有一个a[]数组用来存放满足素数
  环的数比如第一个实例中a[]={1,4,3,2,5,6}当然一个数n可能不止一个序列满足素数环 所以在组成
  一个素数环时要将数组a[]输出 然后在退出一层搜索时将数组a[]和vis[]还原(释放)
  由于题中说明每次都从1开始所以我们首先就可以将1进行标记

*/

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.



Input
n (0 < n < 20).

Output
The 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.

Sample Input
68

Sample Output
Case 1:1 4 3 2 5 61 6 5 2 3 4Case 2:1 2 3 8 5 6 7 41 2 5 8 3 4 7 61 4 7 6 5 8 3 21 6 7 4 3 8 5 2

#include <stdio.h>
#include <string.h>

int vis[21],k,a[21],n;
//判断是否是素数 是素数就返回1 否则就返回0
int prime(int x)
{
    if(x==1)
        return 0;
    int i;
    for(i=2; i*i<=x; i++)
    {
        if(x%i==0)
        {
            return 0;
        }
    }
    return 1;
}
void dfs(int x)
{
    int i;
    if(prime(a[n-1]+a[0])==1&&k==n)
    /*如果最后一个数与1(第一个数)相加仍为一个素数那么就输出数组 在这里有一个
      格式的坑 比如1 4 3 2 5 6 在6的后面是没有空格的->1*4*3*2*5*6(为了便于理解
      这里用*代替空格)
    */
    {
        for(i=0; i<k; i++)
        {
            if(i==0)
                printf("%d",a[i]);
            else
                printf(" %d",a[i]);
        }
        printf("\n");
        //输出一组素数环序列时返回上一层
        return ;
    }
    for(i=2; i<=n; i++)
    {
        if(vis[i]==0&&prime(i+x)==1)
        {
            vis[i]=1;//在i满足条件时要对i进行标记且用数组对i进行保存
            a[k++]=i;
            dfs(i);
            vis[i]=0;//在退出一层的搜索时要将刚刚加入的数还原(标志还原、数组保存的数还原)
            a[k--]=0;
        }
    }
}
int main()
{
    int count=0;
    while(scanf("%d",&n)!=EOF)
    {
        k=1;
        printf("Case %d:\n",++count);
        memset(vis,0,sizeof(vis));
        a[0]=1;//题目当中说明每次都从1开始所以可以先对1进行标记
        vis[1]=1;
        dfs(1);
        printf("\n");//注意这里又有一个格式的坑题目中有说明每个输出实例后要有一个空行
    }
    return 0;
}
0 0