P1069 细胞分裂
P1069 细胞分裂
题解
你看这道题的数据,很大,显然这是一道数学题
那么我们可以用分解质因数做
这道题也就相当于这样的问题
ak = m1m2
求解最小的 k 值
可以把两边进行质因数分解
如果方程有解的话,a 中一定包含 m1的所有质因子,a的质因子可以比 m1 多
所以我们先把 m1 分解质因数,存到结构体 p 里,记录质因子的个数,质因子是什么,以及其指数
来一个新细胞 x 就分解一下这个细胞的质因数
然后枚举 m1 的所有质因子,一旦新细胞 x 没有 m1 的某个质因子,就退出,寻找下一个新细胞
对于 m1 和 x 的公共质因子,他们的指数不一定相同,最后的分裂次数和最大的指数差有关,因为 x 一定是要包含 m1 的,所以找到这个最大的指数差就好了
注意特盘:
如果 m1 是1的话,不用等待,直接就可以开始试验
代码
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; int m1,m2,n; struct node { int cnt,zhi[50005],ci[50005]; //cnt质因子的总个数,zhi[]存质因子,ci[]存质因子的次数 }p,q; //p存储m1,q存储细胞 void fenjie(int x,node &p) //分解质因数,把 x 分解到 p 里 { p.cnt =0; for(int i=2;i*i<=x;i++) { if(x%i==0) { p.zhi[++p.cnt ]=i; p.ci [p.cnt ]=0; do { x/=i; p.ci [p.cnt ]++; }while(x%i==0); } } if(x>1) { p.zhi [++p.cnt ]=x; p.ci [p.cnt ]=1; } } int main() { scanf("%d",&n); scanf("%d%d",&m1,&m2); if(m1==1) { printf("0"); return 0; } //特判 fenjie(m1,p); int ans=-1,x; //x -> 新来的细胞 ,ans初始化-1 for(int i=1;i<=n;i++) { scanf("%d",&x); fenjie(x,q); int maxn=0,nxt=1; //maxn -> 该细胞的分裂次数 ; nxt -> x的质因子下标 int flag=0; //默认无解 for(int j=1;j<=p.cnt ;j++) //枚举m1的每个质因子 { while(q.zhi [nxt]<p.zhi [j]&&nxt<=q.cnt ) nxt++; //寻找x中,m1的质因子 if(q.zhi [nxt]>p.zhi [j]||nxt>q.cnt ) break; //如果找不到就直接退出 int f=p.ci [j]*m2/q.ci [nxt]; if((p.ci [j]*m2)%(q.ci [nxt])) f++; //f记录细胞的分裂次数,如果除不尽的话就向上取整一下 if(maxn<f) maxn=f; //maxn记录的是对于当前这个细胞的分裂次数 //求质因子指数的最大值,因为x要包含m1的每一个质因子 if(j==p.cnt ) flag=1; else flag=0; //标记找到了答案,记为1 //如果找不到答案,前面会break掉 } if(flag&&(ans==-1||ans>maxn)) ans=maxn; //如果(有答案 &&(答案是第一次找到 || 原来答案比现在找到的大) ) //更新答案为一个最小值 } printf("%d\n",ans); return 0; }
~Thanks~
~神仙 ych QWQ~