0
点赞
收藏
分享

微信扫一扫

质数环,回溯+DFS: prime circle

阿尚青子自由写作人 2022-04-13 阅读 94
c++dfs算法

质数环,一道ACM题,使用了回溯+DFS

题目描述

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.

输入

n (0 < n < 20).
(multi test case)

输出

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.

样例输入

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

分析

        如果符合条件,放入进行后续DFS尝试,若失败则取出,尝试其他可能。

        经典的回溯思想。

#include <bits/stdc++.h>
using namespace std;

vector<int> ans;
int n;
int visited[20];
int l = 1;

int isPrime(int num){
    //判断是否为质数
    for(int i = 2;i<num/2+1;i++)
        if(num%i == 0)
            return 0;
    return 1;
}
void traceback(int now,int num){
    //回溯+DFS
    if(now > num&&isPrime(ans.back()+1)){
    //最后一个的判断,因为是环,要首尾相加判断
        for(int i = 0;i<num-1;i++)
            cout<<ans[i]<<" ";
        cout<<ans[num-1]<<endl;
        return;
    }
    for(int i = 1;i<=num;i++){
        if(!visited[i]&&isPrime(ans.back()+i))
        {
            //如果没有visit过且与前项相加为质数,则放入
            ans.push_back(i);
            visited[i] = 1;
            traceback(now+1,num);
            //取出,回溯过程
            visited[i] = 0;
            ans.pop_back();
        }
    }
}
int main()
{
    while(cin>>n){
        ans.clear();
        ans.push_back(1);
        memset(visited,0,sizeof(visited));//全置为0
        visited[1] = 1;
        cout<<"Case "<<l<<":"<<endl;
        traceback(2,n);
        cout<<endl;
        l++;
    }
}
举报

相关推荐

0 条评论