一、问题描述
二、问题分析
先进行吐槽,依旧是题目理解错了,导致一直不能解题(不知道是题目表述有问题还是我理解有问题,太难了!)。通过看解析,那么题目应该是:求从1~N种选取7个合数,最多且存在恰好经过6层就可以与其他所选取的所有合数产生联系的最小的N。个人理解为与所有的数(包括未被选择的质数和合数,而且也没有说必须有刚好经过6层的)产生联系,导致无法求解。
按照书中的题解进行问题理解后只需要a*a, a*b, b*c, c*d, d*e, e*f, f*f就可以达到要求,(如果没有要求必须恰好6层就没必要这样)。那么题解就是找到最小的6个质数,将其按要求排列后能够取得最小值乘值的那个排列。
三、代码实现
1.C/C++实现
#include <iostream>
#define MY_NUM 6
using namespace std;
int minMulti;
int tmp[MY_NUM];
int primes[MY_NUM];
bool used[MY_NUM];
void getPrimes(int n)
{
primes[0] = 2;
int length = 1;
int tmp = 2;
while (length < n && tmp++)
{
bool flag = true;
for (int i = 0; i < length && flag; i++)
if (tmp % primes[i] == 0)
flag = false;
if (flag)
primes[length++] = tmp;
}
}
void getMinMulti(int len)
{
if (len == MY_NUM)
{
int multi = tmp[0] > tmp[len - 1] ? tmp[0] * tmp[0] : tmp[len - 1] * tmp[len - 1];
for (int i = 1; i < len; i++)
multi = multi > tmp[i] * tmp[i - 1] ? multi : tmp[i] * tmp[i - 1];
minMulti = multi < minMulti ? multi : minMulti;
}
for (int i = 0; i < MY_NUM; i++)
{
if (used[i])
continue;
tmp[len++] = primes[i];
used[i] = true;
getMinMulti(len);
used[i] = false;
len--;
}
}
int main()
{
getPrimes(MY_NUM);
minMulti = primes[5] * primes[5];
getMinMulti(0);
cout << minMulti << endl;
}
2.Python实现
# coding=utf-8
import itertools
# 获取 n 个最小的素数
def get_primes(n):
primes = [2, ]
num = 2
while len(primes) < n:
num += 1
flag = True
for prime in primes:
if num % prime == 0:
flag = False
break
if flag:
primes.append(num)
return primes
if __name__ == '__main__':
# 只需要 6 个质数
primes_6 = get_primes(6)
result = []
max_multi = primes_6[-1] ** 2
for item in itertools.permutations(primes_6):
composites = [item[0] ** 2, ]
composites.extend([item[i] * item[i + 1] for i in range(5)])
composites.append(item[-1] ** 2)
tmp_max_multi = max(composites)
if tmp_max_multi < max_multi:
result = composites
max_multi = tmp_max_multi
print(max_multi)
print(result)