UVa524

UVa524  

   输入正整数n,把整数1,2,3,···,n组成一个环,使得相邻两个整数之和均位素数。输出时从整数1开始逆时针排序。同一个环应恰好输出一次。n<=16.

样例输入:
6
样例输出:
1 4 3 2 5 6
1 6 5 2 3 4

枚举排列(比较费时间,跑到n = 16会超时)
#include 
#include 
using namespace std;
int prime[33];
int A[20];
int is_prime(int n){
    for(int i = 2; i < n; i++){
        if(n % i == 0){
            return 0;
        }
    }
    return 1;
}
int main(){
    int n;
    scanf("%d", &n);
    for(int i = 2; i < 33; i++){
        prime[i] = is_prime(i);          //素数表只需从3计算就可以了, 因为两数相加最小是3
    }
    for(int i = 0; i < n; i++) A[i] = i + 1;
    do{
        int ok = 1;
        for(int i = 0; i < n; i++){
            if(!prime[A[i] + A[(i + 1) % n]]){       //%n边界
                ok = 0;
                break;
            }
        }
        if(ok){
            for(int i = 0; i < n; i++){
                printf("%d ", A[i]);
            }
            printf("\n");
        }
    } while(next_permutation(A + 1, A + n));
    return 0;
}


利用回溯法(省时间)
#include 
#include 
using namespace std;
int prime[33], vis[20] = {0};
int A[20], n;
int is_prime(int n){
    for(int i = 2; i < n; i++){
        if(n % i == 0){
            return 0;
        }
    }
    return 1;
}
void dfs(int cur){
    if(cur == n && prime[A[0] + A[n - 1]]){
        for(int i = 0; i < n; i++){
            printf("%d ", A[i]);
        }
        printf("\n");
    } else {
        for(int i = 2; i <= n; i++){
            if(!vis[i] && prime[i + A[cur - 1]]){
                A[cur] = i;
                vis[i] = 1;
                dfs(cur + 1);
                vis[i] = 0;
            }
        }
    }
}
int main(){
    A[0] = 1;
    scanf("%d", &n);
    for(int i = 2; i < 33; i++){
        prime[i] = is_prime(i);        //素数表只需从3计算就可以了, 因为两数相加最小是3
    }
    dfs(1);
    return 0;
}


你可能感兴趣的:(#,Uva)