hdu1016Prime Ring Problem解题报告

来源:互联网 发布:淘宝开店装修教程视频 编辑:程序博客网 时间:2024/05/16 16:57

 

一、    问题描述

Prime Ring Problem

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3809    Accepted Submission(s): 1697

Problem Description

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

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

二、    问题分析与算法实现

N皇后的衍生问题,递归、回溯算法的应用。参考N皇后解题报告。

三、    参考代码

#include <iostream>

using namespace std;

 

const int prime[]={2,3,5,7,11,13,17,19,23,29,31,37}; // 列出40以内的素数

 

int ring[20]; // 用于保存结果的数组 

 

void pr(int n,int max); // 程序核心

int judge(int n); // 判断添加进ring数组的数字是否合法。

int cm(int n,int m); // 判断两个数相加是否是素数

void cin_out(int max); // 输出一组答案

int main()

{

   int count=1,n;

   while(cin>>n)

   {

      ring[0]=1; // 第一个数 始终是1.

      cout<<"Case "<<count<<':'<<endl;

      pr(1,n); // 调用递归函数从“1开始。

      cout<<endl; // 正确的输出格式

      count++;

   }

   return 0;

}

 

void pr(int n,int max)

{

   if(n==max)              // n(即ring的下标)等于max

   {                       // 再判断ring[0]ring[max-1]相加是否是素数。

      if(cm(1,ring[n-1])) // 是则输出然后返回,不是则直接返回。

      cin_out(max);

      return ;

   }

   for(int i=2;i<=max;i++)

   {

      ring[n]=i;    // 挨个的往下找

      if(judge(n)) // ring[n]符合题意则递归调用进行下一步运算。

      {

        pr(n+1,max);

      }

   }

}

int judge(int n)

{

   for(int j=0;j<n;j++)

   {

      if(ring[n]==ring[j]) // ring数组中有相同的元素就返回0.

      {

        return 0;

      }

   }

   if(cm(ring[n],ring[n-1])) // 如果ring[n]ring[n-1]相加是素数则返回1.

   return 1;

   else

   return 0;

}

int cm(int n,int m)

{

   for(int i=0;i<12;i++)

   {

      if((n+m)==prime[i])

      {

           return 1;

      }

   }

   return 0;

}

void cin_out(int max)

{

   int i;

   for( i=0;i<max-1;i++)

   {

      cout<<ring[i]<<' ';

   }

   cout<<ring[i]<<endl;

}

                                                                                          陈元杰 2009-11-18 整理

 

原创粉丝点击