【計蒜客 T2059 --- 細胞分裂】公約數

【計蒜客 T2059 --- 細胞分裂】公約數

題目來源:點擊進入【計蒜客 T2059 — 細胞分裂】

Description

Hanks 博士是 BT (Bio-Tech,生物技術) 領域的知名專家。現在,他正在爲一個細胞實驗做準備工作:培養細胞樣本。

Hanks 博士手裏現在有 N 種細胞,編號從 1−N,一個第 i 種細胞經過 1 秒鐘可以分裂爲 Si 個同種細胞( Si 爲正整數)。現在他需要選取某種細胞的一個放進培養皿,讓其自由分裂,進行培養。一段時間以後,再把培養皿中的所有細胞平均分入 M個試管,形成 M 份樣本,用於實驗。Hanks 博士的試管數 M 很大,普通的計算機的基本數據類型無法存儲這樣大的 M 值,但萬幸的是,M 總可以表示爲 m1 的 m2 次方,即 M=mm21 ,其中 m1,m2 均爲基本數據類型可以存儲的正整數。

注意,整個實驗過程中不允許分割單個細胞,比如某個時刻若培養皿中有 4 個細胞,Hanks 博士可以把它們分入 2 個試管,每試管內 2 個,然後開始實驗。但如果培養皿中有 5 個細胞,博士就無法將它們均分入 2 個試管。此時,博士就只能等待一段時間,讓細胞們繼續分裂,使得其個數可以均分,或是乾脆改換另一種細胞培養。爲了能讓實驗儘早開始,Hanks 博士在選定一種細胞開始培養後,總是在得到的細胞“剛好可以平均分入 M 個試管”時停止細胞培養並開始實驗。現在博士希望知道,選擇哪種細胞培養,可以使得實驗的開始時間最早。

Input

第一行,有一個正整數 N,代表細胞種數。
第二行,有兩正整數 m1,m2,以一個空格隔開,即表示試管的總數 M=mm21.
第三行有 N 個正整數,第 i 個數 Si 表示第 i 種細胞經過 1 秒鐘可以分裂成同種
細胞的個數。
對於 50% 的數據,有 mm21≤30000。
對於所有的數據,有 1≤N≤1e4,1≤m1≤3e4,1≤m2≤1e4,1≤Si≤2e9。

Output

一個整數,表示從開始培養細胞到實驗能夠開始所經過的最少時間(單位爲秒)。
如果無論 Hanks 博士選擇哪種細胞都不能滿足要求,則輸出整數 −1。

Sample Input

1
2 1
3

Sample Output

-1

解題思路

記錄m1的m2次方中所有的公約數。當然我們只需要找m1的公約數即可,然後乘以m2,即可以減少很多計算。

然後判斷輸入的數據中是否全部包含這些公約數,並且記錄最少時間。

AC代碼(C++):

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <map>
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl '\n'
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e5+5;
const int MOD = 1e9+7;

int main(){
    SIS;
    int n,m1,m2,x,len,ans=inf,res;
    vector<int> v,cnt;
    cin >> n >> m1 >> m2;
    for(int i=2;i<=m1;i++){
        if(m1%i==0){
            int pos=0;
            v.push_back(i);
            while(m1%i==0) m1/=i,pos++;
            cnt.push_back(pos*m2);
        }
    }
    len=v.size();
    while(n--){
        res=0;
        cin >> x;
        for(int i=0;i<len;i++){
            if(x%v[i]!=0){
                res=inf;
                break;
            }
            int num=0;
            while(x%v[i]==0) num++,x/=v[i];
            if(cnt[i]%num==0) res=max(res,cnt[i]/num);
            else res=max(res,cnt[i]/num+1);
        }
        ans=min(ans,res);
    }
    if(ans==inf) cout << -1 << endl;
    else cout << ans << endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章