P1069 细胞分裂
首先这道题显然是道数学题(要不然这数据怎么玩)
样例1的解释启发我们这道题可以通过分解质因数做
这个题其实条件等价于求a^x=k(m1^m2)的最小x值
我们可以对两边进行分解质因数
发现如果方程有解,则m1中不能包含a中没有的质因子
但是a1的质因子可以比m1多
那么最小的x就是找到最大的次数差值
#include<bits/stdc++.h> using namespace std; inline int read() { int ans=0; char last=' ',ch=getchar(); while(ch<'0'||ch>'9') last=ch,ch=getchar(); while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar(); if(last=='-') ans=-ans; return ans; } //首先这道题显然是道数学题(要不然这数据怎么玩) //样例1的解释启发我们这道题可以通过分解质因数做 //这个题其实条件等价于求a^x=k(m1^m2)的最小k值 //我们可以对两边进行分解质因数 //发现如果方程有解,则m1中不能包含a中没有的质因子 //但是a1的质因子可以比m1多 //那么最小的x就是找到最大的次数差值 struct prime { int cnt,pn[30001],t[30001]; }p,q;//一个储存题目给的条件,一个储存判断 int n,m1,m2; inline void fenjie(int t,prime& p)//质因数分解2 { p.cnt=0; for(int i=2;i*i<=t;++i) { if(!(t%i)) { p.pn[++p.cnt]=i;//记录第cnt个约数 p.t[p.cnt]=0; do { t/=i; ++p.t[p.cnt];//次数 }while(!(t%i)); } } if(t>1){ p.pn[++p.cnt]=t; p.t[p.cnt]=1; } } int main(){ //freopen("cell.in","r",stdin); //freopen("cell.out","w",stdout); n=read(),m1=read(),m2=read(); if(m1==1) return cout<<0<<endl,0;//先判断一波特殊情况 fenjie(m1,p);//把m1分解,存到p里 int ans,x; ans=-1; for(int i=1;i<=n;i++) { x=read(); fenjie(x,q); int maxn=0,nxt=1; //我们用nxt来存储x的下一个质因子的序号 bool flag=false; if(q.cnt>=p.cnt) //只有要求判断的数的质因子的个数>=题目给的条件的质因子的个数才能继续 for(int j=1;j<=p.cnt;j++)//枚举m1的每一个质因子 { while(q.pn[nxt]<p.pn[j]&&nxt<=q.cnt)++nxt; if(nxt>q.cnt||q.pn[nxt]>p.pn[j])break;//如果没有这个质因子就跳出 int f=p.t[j]*m2/q.t[nxt]; if((p.t[j]*m2)%(q.t[nxt])) f++; //让这两个次数相等,因为有可能不整除,所以还要判断一下,相当于向上取整 if(maxn<f)maxn=f;//求最大值 if(j==p.cnt) flag=1; //标记答案 else flag=0; } if(flag&&(ans==-1||ans>maxn))ans=maxn; } printf("%d\n",ans); return 0; }

浙公网安备 33010602011771号