HDU 1016

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

简单dfs dfs有点菜所以练了一下。此题有两个状态:一个是递归深度(即为数组下标),一个是此时数。dfs也做了不少了,总结一点,dfs实际上是对问题的状态空间的深度优先遍历,是对树的深度优先遍历的映射。和普通暴力的区别就是遍历的方式不同。而且因为有剪枝的存在,能够减低时间复杂度。

题解:

//1016
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int n;
int ans[22];
bool vis[22];
int isprime(int x)
{
  int i;
  if(x<2) return 0;
  else if(x == 2) return 1;
  if(x%2 == 0) return 0;
  for(i = 3;i*i<=x;i+=2)
   if(x%i == 0) return 0;
  return 1;
}
void dfs(int dep,int now)//dep 深度 now 此时的数
{
  if(vis[now]) return ;//跑过直接回溯
  if(!isprime(now+ans[dep-1])) return;//满足题目中相邻的相加是素数
  if(dep == n)//当深度是n时
  {
    if(!isprime(now+ans[1])) return ;//不能忘了最后还要和第一个比较一下
    else {
      ans[dep] = now;
      cout<<1;
    for(int i =2;i<=n;i++)
       cout<<" "<<ans[i];
    cout<<endl;
    return ;
   }
 }
 for(int i=2;i<=n;i++)//符合就递归,不符合就回溯
 {
   ans[dep] = now;
   vis[now] = 1;
   dfs(dep+1,i);
   vis[now] = 0;
 }
}
int main ()
{
  int kase = 0;
  while (cin >> n)
  {
      cout << "Case " << ++kase << ":" << endl;
      memset(vis, 0, sizeof(vis));
      ans[0] = 1;
      dfs(1, 1);
      cout << endl;
  }
  return 0 ;
}

猜你喜欢

转载自blog.csdn.net/strategist_614/article/details/81130257