【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; }
“Make my parents proud,and impress the girl I like.”