HDU 1016 Prime Ring Problem

\[\color{blue}{Prime\;Ring\;Problem} \]

\[\color{green}{Time\;Limit: 4000/2000 MS (Java/Others)\quad Memory\;Limit: 65536/32768 K (Java/Others)} \]


\(\color{CornflowerBlue}{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\).


\(\color{CornflowerBlue}{Input}\)

\(n (0 < n < 20).\)


\(\color{CornflowerBlue}{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.


\(\color{CornflowerBlue}{Sample\;Input}\)

6
8

\(\color{CornflowerBlue}{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

\(\color{CornflowerBlue}{Source}\)

Asia 1996, Shanghai (Mainland China)


\(\color{CornflowerBlue}{Recommend}\)

JGShining | We have carefully selected several similar problems for you: 1010 1241 1312 1072 1242




题目描述

如图所示,环由\(n\)个圆组成。把自然数\(1,2,...,n\)分别放入每个圆,两个相邻圆中的数字之和应该是素数。
注:第一个圆的个数应始终为1。



输入

\(n (0 < n < 20).\)



输出

输出格式如样例所示。 每一行表示环中一系列的圆圈数,从\(1\)开始,包括顺时针和逆时针。数的顺序必须满足上述要求。按字典序打印解决方案。
您将编写完成上述过程的程序。
每组后打印空行。



Pz's solution

1.首先,考虑到最大能拼成的数为\(18+19=37\),可以先预处理出\(1 \sim 40\)之间的质数;

2.在保证前一项与当前搜索项相加为质数的情况下进行搜索;

3.当搜索到最后一个数时,特判一下\(1\)与之相加是否为质数即可;

  • TAG:搜索;质数



PZ.cpp

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 40
int n,T,ans[N],p[N];
bool vis[N],used[N];
void init(){
	vis[0]=vis[1]=1;
	for(int i=2;i<N;++i){
		if(!vis[i]) p[++p[0]]=i;
		for(int j=1;j<=p[0]&&p[j]*i<N;++j){
			vis[p[j]*i]=1;
			if(i%p[j]==0) break;
		}
	}
}
void dfs(int res){
	if(res==n){
		if(!vis[1+ans[n]])
			for(int i=1;i<=n;++i){
				printf("%d%c",ans[i],(i==n ? '\n' : ' '));
			}
		return;
	}
	for(int i=2;i<=n;++i)
		if(!used[i])
			if(!vis[ans[res]+i]){
				ans[res+1]=i;
				used[i]=1;
				dfs(res+1);
				used[i]=0;
			}
}
int main(){
	init();
	while(scanf("%d",&n)!=EOF){
		++T;
		memset(used,0,sizeof(used));
		memset(ans,0,sizeof(ans));
		ans[1]=1;
		printf("Case %d:\n",T);
		dfs(1);
		putchar('\n');//注意样例输出格式 
	}
	return 0;
}
posted @ 2021-01-08 13:27  PotremZ  阅读(121)  评论(2编辑  收藏  举报