038题:
题意:
将192分别与1、2、3相乘:
192 × 1 = 192
192 × 2 = 384
192 × 3 = 576
连接这些乘积,我们得到一个1至9全数字的数192384576。我们称192384576为192和(1,2,3)的连接乘积。
同样地,将9分别与1、2、3、4、5相乘,得到1至9全数字的数918273645,即是9和(1,2,3,4,5)的连接乘积。
对于n > 1,所有某个整数和(1,2, … ,n)的连接乘积所构成的数中,最大的1至9全数字的数是多少?
思路:
首先,我们需要需要想到的是确定范围。所求是对于n>1来说,所以乘数最大是4位数(因为5位数的话,乘数✖️1得到一个5位数,乘数✖️2 最小是5位数,5+5大于9)
我们继续缩小范围:
当乘数是1位数的话,被乘数最多乘到9才能满足乘积是9位数
当乘数是2位数的话,被乘数最多乘到4才能满足乘积是9位数
当乘数是3位数的话,被乘数最多乘到3才能满足乘积是9位数
当乘数是4位数的话,被乘数最多乘到2才能满足乘积是9位数
因此我们只需要判断这样的数的乘积链接是否为全数字即可。对于链接,我们可以通过以下算式进行链接乘积:
res = res * (int)(pow(10, (int)log10(乘积))) + 乘积; //res即链接后的9位数
代码如下:
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <inttypes.h>
#include <algorithm>
#define ll int64_t
#define d int32_t
#define mem(a) memset(a, 0, sizeof(a));
#define N 10000
using namespace std;
d book[10]; //用于标记
d maxx = 0; //存储最终结果
//用于判断数字t,最长乘到n的链接数是否为全数字,如果是返回该全数字,不是返回0
d chooes (d t, d n) {
mem(book);
d res = 0;
d chang = 0;
for (d i = 1; i <= n; i++) {
d val = t * i;
d len = (int)log10(val) + 1;
d vall = val;
chang += len;
while (vall) {
if (vall % 10 == 0 || book[vall % 10]) {
return 0;
}
book[vall % 10] = 1;
vall /= 10;
}
res = res * (int)(pow(10, len)) + val;
if (chang == 9) return res;
}
return res;
}
//用于遍历1,2,3,4位数
void work(d len, d n) {
d low = (int)pow (10, len - 1);
d high = (int)pow (10, len);
for (d i = low; i < high; i++) {
d val = chooes(i, n);
if (val) {
maxx = max(maxx, val);
}
}
}
int main () {
d p[4] = {1, 2, 3, 4};
d q[4] = {9, 4, 3, 2};
for (d i = 0; i < 4; i++) {
work(p[i], q[i]);
}
printf("%" PRId32"\n", maxx);
}
最后结果为:932718654
如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢