Codeforces 516A Drazil and Factorial【暴搜找规律+贪心】

本文介绍了一个名为Draziland Factorial的游戏,玩家需要找到一个不含0和1的最大整数x,使得x的各位数字的阶乘之积等于给定数a的各位数字的阶乘之积。文章提供了求解思路及AC代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A. Drazil and Factorial
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Drazil is playing a math game with Varda.

Let's define for positive integerx as a product of factorials of its digits. For example,.

First, they choose a decimal number a consisting ofn digits that contains at least one digit larger than1. This number may possibly start with leading zeroes. Then they should find maximum positive numberx satisfying following two conditions:

1. x doesn't contain neither digit 0 nor digit 1.

2. =.

Help friends find such number.

Input

The first line contains an integer n (1 ≤ n ≤ 15) — the number of digits ina.

The second line contains n digits of a. There is at least one digit in a that is larger than1. Number a may possibly contain leading zeroes.

Output

Output a maximum possible integer satisfying the conditions above. There should be no zeroes and ones in this number decimal representation.

Examples
Input
4
1234
Output
33222
Input
3
555
Output
555
Note

In the first case,


题目大意:

定义一个F(a)=a的每个位子上的数的阶乘相乘。

给你一个数a,让你找一个数x,使得x中没有0也没有1.并且x尽可能的大。


思路:


1、肯定我们是将a中能够拆分的数进行拆分,比如4!=2!*2!*3!

那么我们肯定第一个考虑的问题就是从2~9这些数怎样拆分才能使得拆分出来的数字量最大,因为拆分出来的数字量越大,我们能够组成的数x长度也就越大,长度也大的数,数也就越大。


2、那么我们暴搜判断每个阶乘数最多能够拆分出来几个数,这几个数分别都是多少?

暴力处理代码:

运行结果对应每一行的含义就是对应当前这个阶乘数能够拆分成哪些接成数(包括几个)

#include<stdio.h>
#include<string.h>
using namespace std;
#define ll __int64
int vis[15];
char a[20];
ll jiecheng[20];
void init()
{
    for(int i=2;i<=9;i++)
    {
        ll sum=1;
        for(int j=1;j<=i;j++)
        {
            sum*=j;
        }
        jiecheng[i]=sum;
    }
}
void Dfs(long long int now,long long int n)
{
    if(now>n)return ;
    else if(now==n)
    {
        for(int i=2;i<=9;i++)
        {
            printf("%d ",vis[i]);
        }
        printf("\n");
        return ;
    }
    for(int i=2;i<=9;i++)
    {
        vis[i]++;
        Dfs(now*jiecheng[i],n);
        vis[i]--;
    }
}
int main()
{
    int n;
    memset(vis,0,sizeof(vis));
    init();
    for(int i=2;i<=9;i++)
    {
        printf("%d\n",i);
        Dfs(1,jiecheng[i]);
    }
}

3、那么根据暴力处理出来的结果,我们对应进行处理每个数能够拆分出哪些数,然后此时拆分出来的数一共有多长也就能够确定下来了。最终将每个数从大到小输出即可。


Ac代码:

#include<stdio.h>
#include<string.h>
using namespace std;
int vis[15];
char a[20];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(vis,0,sizeof(vis));
        scanf("%s",a);
        for(int i=0;i<n;i++)
        {
            if(a[i]=='0'||a[i]=='1')continue;
            if(a[i]=='2')vis[2]++;
            if(a[i]=='3')vis[3]++;
            if(a[i]=='4')vis[3]++,vis[2]+=2;
            if(a[i]=='5')vis[5]++;
            if(a[i]=='6')vis[5]++,vis[3]++;
            if(a[i]=='7')vis[7]++;
            if(a[i]=='8')vis[7]++,vis[2]+=3;
            if(a[i]=='9')vis[2]++,vis[3]+=2,vis[7]++;
        }
        for(int i=9;i>=2;i--)
        {
            for(int j=0;j<vis[i];j++)
            {
                printf("%d",i);
            }
        }
        printf("\n");
    }
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值