【题目描述】
Hanks 博士是BT (Bio-Tech,生物技术) 领域的知名专家。现在,他正在为一个细胞实验做准备工作:培养细胞样本。
Hanks 博士手里现在有NN 种细胞,编号从1∼N1∼N,一个第ii 种细胞经过11 秒钟可以分裂为SiSi 个同种细胞(SiSi 为正整数)。现在他需要选取某种细胞的一个放进培养皿,让其自由分裂,进行培养。一段时间以后,再把培养皿中的所有细胞平均分入MM 个试管,形成MM 份样本,用于实验。Hanks 博士的试管数MM 很大,普通的计算机的基本数据类型无法存储这样大的MM 值,但万幸的是,MM 总可以表示为m1m1 的m2m2 次方,即M=m1m2M=m1m2,其中m1m1,m2m2 均为基本数据类型可以存储的正整数。
注意,整个实验过程中不允许分割单个细胞,比如某个时刻若培养皿中有44 个细胞,Hanks 博士可以把它们分入22 个试管,每试管内22个,然后开始实验。但如果培养皿中有55个细胞,博士就无法将它们均分入22个试管。此时,博士就只能等待一段时间,让细胞们继续分裂,使得其个数可以均分,或是干脆改换另一种细胞培养。
为了能让实验尽早开始,Hanks 博士在选定一种细胞开始培养后,总是在得到的细胞“刚好可以平均分入MM 个试管”时停止细胞培养并开始实验。现在博士希望知道,选择哪种细胞培养,可以使得实验的开始时间最早。
【输入】
共有三行。
第一行有一个正整数 NN,代表细胞种数。
第二行有两个正整数 m1m1,m2m2,以一个空格隔开, m1m2m1m2即表示试管的总数MM。
第三行有 NN 个正整数,第ii 个数SiSi 表示第ii 种细胞经过11 秒钟可以分裂成同种细胞的个数。
【输出】
共一行,为一个整数,表示从开始培养细胞到实验能够开始所经过的最少时间(单位为秒)。
如果无论 Hanks 博士选择哪种细胞都不能满足要求,则输出整数-11。
【输入样例】
1
2 1
3
【输出样例】
-1
【提示】
【输入输出样例1 说明】
经过11秒钟,细胞分裂成33个,经过22 秒钟,细胞分裂成99个,……,可以看出无论怎么分裂,细胞的个数都是奇数,因此永远不能分入22个试管。
【输入输出样例 2】
输入:
2
24 1
30 12
输出:
2
【输入输出样例2 说明】
第 11 种细胞最早在33 秒后才能均分入2424 个试管,而第22 种最早在22 秒后就可以均分(每试管144/(241)=6144/(241)=6 个)。故实验最早可以在22秒后开始。
【数据范围】
对于 50%的数据,有m1m2≤30000m1m2≤30000。
对于所有的数据,有1≤N≤10000,1≤m1≤30000,1≤m2≤10000,1≤Si≤2,000,000,0001≤N≤10000,1≤m1≤30000,1≤m2≤10000,1≤Si≤2,000,000,000。\
介绍
这题很难,所以我就不多说了。QWQ ~
展示代码!!!
#include<bits/stdc++.h>
using namespace std;
int read(){
char ch=getchar();
int a=0,x=1;
while(ch<'0'||ch>'9'){
if(ch=='-') x=-x;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
a=(a<<3)+(a<<1)+(ch-'0');
ch=getchar();
}
return a*x;
}
int n,m1,m2,minx,ggbound,m,s,q,t,flag,tot,ans,tots,totq;
int S[10001];
int gcd(int a,int b){
if(b==0) return a;
else return gcd(b,a%b);
}
int main(){
n=read();
m1=read();
m2=read();
minx=1e9;
if(m1==1){cout<<0;return 0;}
for(int i=1;i<=n;i++)S[i]=read();
for(int i=1;i<=n;i++){
tot=0;
m=m1;
s=S[i];
flag=1;
t=0;
while(m!=1){
ggbound=gcd(m,s);
if(ggbound==1){flag=0;break;}
m/=ggbound;
q=s/ggbound;
s=ggbound;
t++;
}
if(flag){
int gc=gcd(q,s);
if(gc!=1&&gc!=s){
totq=0;tots=0;
while(q%gc==0){
totq++;
q/=gc;
}
while(s%gc==0){
tots++;
s/=gc;
}
if((t*m2*tots+totq*(t-1)*m2)%(tots+totq)==0)ans=(t*m2*tots+totq*(t-1)*m2)/(tots+totq);
else ans=(t*m2*tots+totq*(t-1)*m2)/(tots+totq)+1;
minx=min(minx,ans);
}
else{
while(q%s==0){
tot++;
q/=s;
}
if((t*m2+tot*(t-1)*m2)%(tot+1)==0)ans=(t*m2+tot*(t-1)*m2)/(tot+1);
else ans=(t*m2+tot*(t-1)*m2)/(tot+1)+1;
minx=min(minx,ans);
}
}
}
if(minx==1e9)cout<<-1;
else cout<<minx;
return 0;
}