链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网题目描述
kotori拿到了一些正整数。她决定从每个正整数取出一个素因子。但是,kotori有强迫症,她不允许两个不同的正整数取出相同的素因子。
她想知道,最终所有取出的数的和的最小值是多少?
注:若 a mod k==0 ,则称 kkk 是 aaa 的因子。若一个数有且仅有两个因子,则称其是素数。显然1只有一个因子,不是素数。
输入描述:
第一行一个正整数 nnn ,代表kotori拿到正整数的个数。 第二行共有 nnn 个数 aia_iai,表示每个正整数的值。 保证不存在两个相等的正整数。输出描述:
一个正整数,代表取出的素因子之和的最小值。若不存在合法的取法,则输出-1。示例1
输入
4 12 15 28 22输出
17说明
分别取3,5,7,2,可保证取出的数之和最小示例2
输入
5 4 5 6 7 8输出
-1
比赛前坐了两个小时车,开始比赛二十分钟了才进去比赛,前面几题比较简单,但卡在这题,就有一种很简单的感觉,总之就是通过素数筛找到所有素数,然后遍历一下得到所有数的素因数,结果一直卡在最后一步,不知道怎么从每个数组中取一个不重复的数使得答案最小,当时真是做迷糊了,感觉很简单很熟悉,但就是写不出来,一看数据规模也很小,就是暴力不出来,结果后来才想起来自己以前最擅长的dfs.... 当时是一点都想不起来,连dfs都忘了。
ac代码
#include <bits/stdc++.h>
#include <cstring>
#include <unordered_map>
using namespace std;
int n, arr[110];
int s[10010];
int b[10010];
int cnt = 1;
int ans = 999999999;
unordered_map<int, vector<int>> mpp;
void dfs(int x, int y, unordered_map<int, int> mp) {
if (x > n) {
if (mp.size() == n ) ans = min(ans, y);
return;
}
for (int i = 0; i < mpp[arr[x]].size(); i++) {
int f = mpp[arr[x]][i];
if (mp[f] > 0) continue;
else {
mp[f]++;
dfs(x + 1, y + f, mp);
mp[f]--;
mp.erase(f);
}
}
return;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> arr[i];
for (int i = 2; i <= 1000; i++) {
if (b[i] == 0)
s[cnt++] = i;
for (int j = i + i; j < 1000; j += i) {
b[j] = 1;
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; s[j] <= arr[i]; j++) {
if (arr[i] % s[j] == 0) {
mpp[arr[i]].push_back(s[j]);
}
}
}
for (int i = 0; i < mpp[arr[1]].size(); i++) {
unordered_map<int, int> mp;
mp[mpp[arr[1]][i]]++;
dfs(2, mpp[arr[1]][i], mp);
}
if (ans == 999999999) cout << -1;
else cout << ans;
}
总之就是非常懊悔。。