Description
给定一个数n,要求对 [1,n]里面的整数重排序,使得相邻的两数和为质数,若能且有多个结果输出按字典序排列的第一个,若不能实现输出-1 。spa
Input and Output
示例 1:code
输入:3 输出:1 2 3排序
示例 2:递归
输入:5 输出:1 4 3 2 5ip
Solution
-
思路: 用dfs例举全部组合,判断是否知足条件。 如何例举全部组合?参考领扣的全排列那题(cur位置元素和cur后面元素一一交换)io
-
剪枝: 不是等排列完成了才判断是否知足,而是交换一个次就判断一次。cur位置前面是已排的,cur位置后是未排的。每当cur位置元素和后面元素交换时,就判断cur位置和cur-1位置元素和是否是质数,若不是那么这个方案就不用再继续下去了。class
-
dfs中止: 一旦出现结果,整个递归所有结束,因此调用dfs前要钱判断是否已获得结果集合
-
缩短判断是否为质数时间 把全部质数放到集合中,要判断就到集合中找,而不须要依据公式在计算一遍di
#include <stdio.h> #include <vector> #include <set> std::set<int> zhishus;//质数集 std::vector<int> result; int iszhishu(int num) { //检查num是否为质数 if(num<=0) return 0; int i; for(i=2; i*i<=num; i++) { if(num%i==0) return 0; } return 1; } void dfs(std::vector<int> nums, int cur){ //全排列 if(cur==nums.size()) { result=nums; return; } int i; for(i=cur; i<nums.size(); i++){ std::swap(nums[cur],nums[i]); if( result.empty() && (cur==0 || zhishus.count(nums[cur]+nums[cur-1]) ) ) dfs(nums, cur+1); std::swap(nums[cur],nums[i]); } } int main() { int n,i,j; scanf("%d",&n); if(n<5) { for(i=1; i<=n; i++) printf("%d ",i); return 0; } //构造质数集 for(i=1; i<=n+n; i++) if(iszhishu(i)) zhishus.insert(i); //构造 1~n std::vector<int> nums; for(i=1; i<=n; i++) nums.push_back(i); //全排列 dfs(nums,0); if(result.empty()) printf("-1"); else for(i=0; i<result.size(); i++) printf("%d ",result[i]); return 0; }