1. 程式人生 > >NOIP複習模擬賽day5

NOIP複習模擬賽day5

前言 

今天的題目真TM的♂......

題目

1.小半

(half.pas/c/cpp)

【問題描述】

“釋然、慵懶、盡歡,

時間風乾後你與我再無關,

沒答案,怎麼辦,看不慣自我欺瞞。

燈火闌珊,釋然的少年寫下了n個正整數,它們的乘積為p。

月色旖旎,少年忽然想到,如果把p再乘上一個正整數q能讓它們的積為某個數的階乘,則稱這個數的階乘為完美階乘,這個數則為完美數,他厭倦了那些紛擾,只想要知道完美數的最小值,希望你能告訴他。

“燈火闌珊,

我的心借了你的光是明是暗。——《小半》

【輸入】

共兩行。

第一行一個正整數n

第二行n個正整數a[i],代表少年寫下的n

數。

【輸出】

共一行

一個正整數,代表完美數的最小值。

【輸入輸出樣例】

1

6

3

樣例解釋:當p=6,q=1時,p*q=3!

【資料範圍】

對於10%的資料,n<=10

對於30%的資料,n<=1000

對於100%的資料,n<=100000,a[i]<=100000

 

官方題解:

10%~30%:各種暴力
100%:題目要求一個最小的m使m!包含p這個因子。
可以把p分解質因數,假設p=∏ai^bi(ai為質數),那麼只要m!包含了每個ai^bi,m!就包含p。
所以對於每個ai^bi,分別求出滿足條件的最小的m,取最大值即可。
怎麼求m?
先看一個簡單的問題:
27!裡面有多少個3相乘?
27!=1*2*...*27
包含1個3的數有27/(3^1)=9個
包含2個3的數有27/(3^2)=3個
包含3個3的數有27/(3^3)=1個
總共:9+3+1=13個
所以27!裡面有13個3相乘。
用這個方法就可以求得m!有多少個ai相乘,二分判斷即可。

這是一道水題,相信大家都切了o(* ̄︶ ̄*)o

官方標程:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #define fo(i,a,b) for(int i=a;i<=b;i++)
 6 #define fd(i,a,b) for(int i=a;i>=b;i--)
 7 #define maxn 100005
 8 #define ll long long
 9
using namespace std; 10 11 int bz[maxn],pri[maxn],fr[maxn]; 12 13 int cnt[maxn]; 14 15 int a[maxn][2],tot; 16 17 int n; 18 19 void pre(){ 20 fo(i,2,100000) { 21 if (bz[i]==0) pri[++pri[0]]=i,fr[i]=i; 22 fo(j,1,pri[0]) { 23 if (i * pri[j]>100000) break; 24 bz[i*pri[j]]=1; 25 fr[i*pri[j]]=pri[j]; 26 if (i % pri[j]==0) break; 27 } 28 } 29 } 30 31 void pred(){ 32 int x; 33 scanf("%d",&x); 34 while (x!=1) { 35 cnt[fr[x]]++; 36 x=x / fr[x]; 37 } 38 } 39 40 ll count(ll x,ll y){ 41 ll ret=0; 42 while (x>=y) { 43 ret=ret+x / y; 44 x=x / y; 45 } 46 return ret; 47 } 48 49 bool check(ll x) { 50 fo(i,1,tot) if (count(x,a[i][0])<a[i][1]) return 0; 51 return 1; 52 } 53 54 int main(){ 55 pre(); 56 scanf("%d",&n); 57 fo(i,1,n) pred(); 58 fo(i,1,100000) if (cnt[i]) { 59 ++tot; 60 a[tot][0]=i; 61 a[tot][1]=cnt[i]; 62 } 63 if (tot==0) { 64 cout<<1; 65 return 0; 66 } 67 ll ans=0,l=2,r=(ll)1e10; 68 while (l<=r) { 69 ll mid=(l+r) / 2; 70 if (check(mid)) { 71 r=mid-1; 72 ans=mid; 73 } 74 else l=mid+1; 75 } 76 cout<<ans; 77 return 0; 78 }
View Code

 

自己bb的題解:  

  首先,這一題是真的♂,我打了一個早上,才推出了一半。(我還是太菜了)(才發現陳徽桓是個大佬,如果大家想要了解更多資訊,請手動百度陳徽桓;)