【NOIP模拟】函数

【问题描述】 对于一个整数,定义 f(x)为他的每个数位的阶乘的乘积。例如 f(135)=1! * 3! * 5! = 720。给出一个数 a(可以包含前缀零),a 满足他的至少一个数位大于 1。我们要求出最 大 的整数 x,其中 x 不含 0 或 1,并且满足 f(a) = f(x)。

【输入】 第一行一个整数 n,表示 a 的长度。 接下来一个整数 a。

【输出】 一行一个整数 x 表示答案。

【输入样例 1】 4 1234

【输出样例 1】 33222

【样例 1 说明】 1! * 2! * 3! * 4! = 3! * 3! * 2! * 2! * 2!

【输入样例 2】 2 03

【输出样例】 3

【样例 2 说明】 0! * 3! = 3!

【数据范围】 对 30%的输入数据 :n≤2 对 100%的输入数据 :n≤15

 

分析:水。我想得好复杂。

把每个数字的阶乘出现的数的个数统计一下,然后对7,3,5三个质数进行先选出来的操作(因为要消去这几个数必须有他们本身的阶乘出现),再对剩余的数字拆分

事实上可以直接拆分4,6,8,9,拆成什么参考我的第二部分的分解

 

#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<iostream>
using namespace std;
#define N 100
char s[N];
int cnt[N],cnt2[N],num[N],ans[N*100];
int n,cot,limit,limax;

inline void getnum(int x)
{
    for(int i=x;i>=2;i--)
        cnt[i]++;
}

inline void divide(int x)
{
    if(x==2)cnt2[2]+=cnt[2];
    if(x==4)cnt2[2]+=cnt[4]*2;
    if(x==6){cnt2[2]+=cnt[6],cnt2[3]+=cnt[6];}
    if(x==8)cnt2[2]+=cnt[8]*3;
    if(x==9)cnt2[3]+=cnt[9]*2;
}

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>s[i];num[i]=s[i]-'0';
        getnum(num[i]);
        limit=max(limit,num[i]);
    }
    limax=limit;
    if(limit>7)limit=7;
    if(limit%2==0&&limit!=2)limit--;
    for(int i=limit;i>=3;i-=2)
    {
        int k=cnt[i];
        for(int j=1;j<=k;j++)
            ans[++cot]=i;
        for(int j=i;j>=2;j--)
            cnt[j]-=k;
    }
    for(int i=2;i<=limax;i++)
        if(cnt[i])
            divide(i);
    for(int i=3;i>=2;i--)
    {
        if(!cnt2[i])continue;
        int k=cnt2[i];
        for(int j=1;j<=k;j++)
            ans[++cot]=i;
        for(int j=i;j>=2;j--)
            cnt2[j]-=k;
    }
    sort(ans+1,ans+1+cot);
    for(int i=cot;i>=1;i--)
        cout<<ans[i];
    return 0;
 } 

 

posted @ 2018-08-07 23:50  WJEMail  阅读(160)  评论(0编辑  收藏  举报