[HPUOJ] 问题 D: zz’s math problem Ⅰ

题目描述

有些人心如花木,皆向阳而生
|《剑来》
zz很喜欢数学,但是他又是一个数学渣,我们称这种生物叫做学渣,
zz又碰到了一个数学小问题,定义一个函数P (x)
例如:P (123) = 1! ∗ 2! ∗ 3! 现在需要找到的就是最大的大于等于x大的数z的函数值和x相等,
即P (z) = P (x) 当然z这个数不能包含1或者0
还请输出最大的符合要求数z(不一定比x大)

输入

第1行输入T (1 ≤ T ≤ 20)组数据
第2行输入n(1 ≤ n ≤ 100),表示x的数字个数
第3行输入正整数 x

输出

输出最大的z(数据保证x内含大于1的数,所以z必定有解)

样例输入

2
4
1234
3
555

样例输出

33222
555

提示

第一个样例f(1234) = 1! ∗ 2! ∗ 3! ∗ 4! = 288 = f(33222)

这个问题非常有意思

假如跟着提示走一波

很容易可以发现9! = 362880

按题目要求 最大100个9!相乘肯定是爆天爆地的

再者 100路径深度分支也太多 不可接受

所以用搜索的方法绝对行不通的

其实搜索方向毙掉那题目就迎刃而解了

思路立刻转向等量代换

1 1 2 6 24 120 720 5040 40320 362880 (0! 到 9!)

很容易发现0! 和 1! 是不可能出现的 无数个1相乘还是本身;

剩下的就慢慢枚举 分解子问题

24 = 6 * 2 * 2 推出 4 ! = 3! *  2!  * 2!

720 = 120 * 6

40320 = 5040 * 8        8 = 2 * 2 * 2

362880 = 5040 *  72      72 = 6 * 6 * 2

这个分解的过程也很有意思 就根据0! 到9! 递归分解下去就行

这四个可分解的数换为分解后的加到答案串里

不可分解的原样加回

0 和 1 就不加了

答案串按大顶sort一下输出即可

#include <iostream>
#include <algorithm>
using namespace std;

typedef long long ll;

//const int MAXN = 1e3 + 10;

bool cmp(char a, char b)
{
    return a > b;
}

int main()
{
    //int arr[10] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};

    int N;

    cin>>N;

    while(N--)
    {

        string ans = "";

        ll len, tlen;

        cin>>len;

        char tmp;

        while(len --)
        {
            cin>>tmp;

            if(tmp == '4')
            {
                ans = ans + "322"; 
            }
            else if(tmp == '6')
            {
                ans = ans + "53"; 
            }
            else if(tmp == '8')
            {
                ans = ans + "7222"; 
            }
            else if(tmp == '9')
            {
                ans = ans + "7332"; 
            }
            else if(tmp == '0' || tmp == '1')
            {
                continue;
            }
            else
            {
                ans = ans + tmp;
            }
        }

        sort(ans.begin(), ans.end(), cmp);

        cout<<ans<<endl;

    }
    return 0;
}
原文地址:https://www.cnblogs.com/zeolim/p/12270551.html