题目描述
有些人心如花木,皆向阳而生
|《剑来》
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;
}