/*
Name: ZOJ Problem Set - 1457
Date: 07/11/13 11:18
Description:
题意:将N个数字按一定序列排,相邻数字之和必须为素数,头和尾相邻。按字典序升序输出所有可能。
思路:dfs历遍所有可能性即可,要注意剪枝(较简单),还有就是考虑奇数和偶数,否则必定超时(一开始没注意)
另外一点很有意思的是,我在自己电脑上运行的时候,n=18就基本等不到结果了,我一开始以为肯定超时的,后来交上去试试,结果过了
时间190ms 空间172KB
*/
#include<stdio.h>
#include<string.h>
bool prime[105];
int vis[105],N,count;
void dfs(int i);
void not_prime();
void output(int i);
int main(){
int ri=0;
not_prime();
while(scanf("%d",&N)!=EOF)
{
printf("Case %d:\n",++ri);
if(N%2){
puts("");
continue;
}
memset(vis,0,sizeof(vis));
count=1;
dfs(1);
puts("");
}
return 0;
}
void dfs(int i){
if(count==N){
if(prime[i+1]==0){
output(i);
puts("");
}
return;
}
int j;
for(j=2;j<=N;j++){
if(vis[j]+prime[i+j]==0){//首先j必须没有使用过,且符合素数规则
vis[j]=i; //先考虑如果将j这个数加入序列
count++;
dfs(j);
vis[j]=0; //然后不将j这个数加入序列
count--;
}
}
}
void not_prime(){
memset(prime,0,sizeof(prime));
int i,j;
for(i=2;i<100;i++){
for(j=2;j<=i/2;j++){
if(i%j==0){
prime[i]=1;
continue;
}
}
}
}
void output(int i){ //这里可以定义一个输出数组来储存序列,当数组满N的时候输出,
if(i==1){ // 也可以用数组方式的链表来储存,个人喜欢第二种
printf("1");
return ;
}
output(vis[i]);
printf(" %d",i);
}
ZOJ Problem Set - 1457 解题报告
最新推荐文章于 2024-10-09 21:07:21 发布