首页 > 技术文章 > 【万能的搜索】素数环

Alan-Anders 2020-09-05 10:39 原文

初三一年没有碰电脑,再次开始敲代码的时候,发现已经基本啥也不会了

幸好我天赋异禀,迅速恢复训练让我找回了敲代码的感觉……

——————————————————————————————————分割线————————————————————————————————————————————

由于忘得比较多,所以先来一道经典的题回忆一下搜索题目

题目描述

PDF

输入格式

输出格式

题意翻译

输入正整数 nnn,把整数 1,2,…,n1,2,\dots ,n1,2,,n 组成一个环,使得相邻两个整数之和均为素数。输出时,从整数 111 开始逆时针排列。同一个环恰好输出一次。n≤16n\leq 16n16,保证一定有解。

多组数据,读入到 EOF 结束。

iii 组数据输出前加上一行 Case i:

相邻两组数据中间加上一个空行。

输入输出样例

【输入】

6
8

【输出】

 

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

 

解题思路

这是一道经典的深搜题,还是比较简单的,搜索加上判断素数就好了,只是这道题的输出格式很坑

代码

#include<iostream>
#include<cmath>
#include<cstring>
#define N 20
using namespace std;
int n;
int vis[N], a[N];    //vis存每个数有没有被用过, a存素数环 
int pd (int x){    //判断素数 
    int sx=sqrt(x);
    for (int i=2; i<=sx; i++){
        if (x % i == 0) return 0;
    }
    return 1;
}
void dfs(int x){    //搜索 
    if (x == n && pd(a[0]+a[n-1])){     
        cout<<a[0];
        for (int i=1; i<n; i++)
            cout<<" "<<a[i];
        cout<<endl;
    }
    for (int i=2; i<=n; i++){
        if (!vis[i] && pd(a[x-1]+i)){
            a[x]=i;
            vis[i]=1;
            dfs(x+1);
            vis[i]=0;
        }
    }
}
int main()
{
    int num=0;
    while (cin>>n){
        memset(vis, 0, sizeof(vis));
        a[0]=1;
        num++;
        if (num>1) cout<<endl;
        cout<<"Case "<<num<<":"<<endl;
        dfs(1); 
    }
    return 0;
 } 

 

推荐阅读