问题描述
小M拿到一个数组,她可以进行多次操作,每次操作可以选择两个元素 aiai 和 ajaj,并选择 aiai 的一个因子 xx,然后将 aiai 变为 ai/xai/x,并将 ajaj 变为 aj×xaj×x。她的目标是通过有限次操作,使得数组中的每个元素最多只包含一种素因子。
素因子的定义是:若 xx 能被素数 pp 整除,那么 pp 是 xx 的一个素因子。例如,1212 的素因子有 22 和 33。
你的任务是判断是否有可能通过有限次操作,使数组中的每个元素最多只包含一种素因子。如果可以,输出 "Yes",否则输出 "No"。
测试样例
样例1:
输入:
n = 4 ,a = [1, 2, 3, 4]
输出:'Yes'
样例2:
输入:
n = 2 ,a = [10, 12]
输出:'No'
样例3:
输入:
n = 3 ,a = [6, 9, 15]
输出:'Yes'
思路
题目思路主要就是进行素因子的转移,像样例3就是把3素因子都转移到9上即可,所以最后问题就可以简化成统计素因子个数,小于元素个数即可成功满足条件
代码
#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
using namespace std;
// 分解素因子
vector<int> primeFactors(int num) {
vector<int> factors;
for (int i = 2; i * i <= num; ++i) {
if (num % i == 0) {
factors.push_back(i);
while (num % i == 0) num /= i;
}
}
if (num > 1) factors.push_back(num);
return factors;
}
string solution(int n, vector<int>& a) {
// 素因子集合
unordered_set<int> uniqueFactors;
for (int i = 0; i < n; ++i) {
vector<int> factors = primeFactors(a[i]);
for (int factor : factors) {
uniqueFactors.insert(factor);
}
}
// 对比素因子个数和数组元素个数
if (uniqueFactors.size() <= n) {
return "Yes";
} else {
return "No";
}
}
int main() {
vector<int> a1 = {1, 2, 3, 4};
vector<int> a2 = {10, 12};
vector<int> a3 = {6, 9, 15};
cout << (solution(4, a1) ) << endl;
cout << (solution(2, a2) ) << endl;
cout << (solution(3, a3) ) << endl;
return 0;
}
问题描述
小U决定在一个 m×nm×n 的地图上行走。地图中的每个位置都有一个高度,表示地形的高低。小U只能在满足以下条件的情况下移动:
- 只能上坡或者下坡,不能走到高度相同的点。
- 移动时必须交替进行:上坡后必须下坡,下坡后必须上坡,不能连续上坡或下坡。
- 每个位置只能经过一次,不能重复行走。
任务是帮助小U找到他在地图上可以移动的最大次数,即在符合所有条件的前提下,小U能走过的最大连续位置数量。
例如在以下2x2的地图中:
1 2
4 3
中庸行者可以选择移动顺序 3 -> 4 -> 1 -> 2,最大移动次数为3。
测试样例
样例1:
输入:
m = 2, n = 2, a = [[1, 2], [4, 3]]
输出:3
样例2:
输入:
m = 3, n = 3, a = [[10, 1, 6], [5, 9, 3], [7, 2, 4]]
输出:8
样例3:
输入:
m = 4, n = 4, a = [[8, 3, 2, 1], [4, 7, 6, 5], [12, 11, 10, 9], [16, 15, 14, 13]]
输出:11
思路
就是想试着用dfs, 可以涉及回溯,但是复杂度很高,所以在想有没有什么其他方法。于是想到了dp,可以通过更新从每一个开始上下坡可以走的最大步数来解决问题,所以可以先找一个点用深度或者广度优先搜索得到部分答案,然后进行相应更新反推。
可能涉及问题:如何选第一个点?走最大步数要区分上下坡的最大步数
没写出来代码嘿嘿。。。