虫虫首页|资源下载|资源专辑|精品软件
登录|注册

您现在的位置是:首页 > 技术阅读 >  每日一题:优美的排列

每日一题:优美的排列

时间:2024-02-14

题目526:优美的排列

假设有从 1 到 N 的 N 个整数,如果从这 N 个数字中成功构造出一个数组,使得数组的第 i 位 (1 <= i <= N) 满足如下两个条件中的一个,我们就称这个数组为一个优美的排列。条件:

  • 第 i 位的数字能被 i 整除

  • i 能被第 i 位上的数字整除

现在给定一个整数 N,请问可以构造多少个优美的排列?

示例1:

输入: 2
输出: 2
解释:

第 1 个优美的排列是 [1, 2]:
第 1 个位置(i=1)上的数字是1,1能被 i(i=1)整除
第 2 个位置(i=2)上的数字是2,2能被 i(i=2)整除

第 2 个优美的排列是 [2, 1]:
第 1 个位置(i=1)上的数字是2,2能被 i(i=1)整除
第 2 个位置(i=2)上的数字是1,i(i=2)能被 1 整除

说明:

  1. N 是一个正整数,并且不会超过15。

分析

回溯思想,题目明确说明N不会超过15,类似于暴力解法,但是带有剪枝策略,在第1-N个位置,依次放置数字,每个位置都尝试1-N,看是否合适,同时记录下这个数字使用的情况。如果不合适在当前位置直接换下一个数字,如果合适则有两种选择,第一在当前位置换一个数字尝试,第二继续回溯,当前位置使用这个数字,下一位置继续尝试1-N。

代码

class Solution {public:   int countArrangement(int N) {       used.resize(N + 1, false);       BackTrace(N, 1);       return ret;  }
int ret = 0; vector<bool> used; void BackTrace(int N, int idx) { if (idx > N) { // 所有位置都已经有合适的数字,结果加1 ret += 1; return; } for (int i = 1; i <= N; ++i) { // 过滤掉不合适的数字和已经使用过的数字 if (!used[i] && ((idx % i == 0) || (i % idx == 0))) { used[i] = true; BackTrace(N, idx + 1); used[i] = false; } } }};


C++线程池的实现之格式修订版

每日一题:N皇后问题

点此留言