问题标题: 酷町堂:1456 细 胞 分 裂

0
0
已解决
汪恺恒
汪恺恒
中级启示者
中级启示者

Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家。现在,他正在为一个细胞实验做准备工作:培养细胞样本。

Hanks 博士手里现在有 N 种细胞,编号从 1~N,一个第 i 种细胞经过 1 秒钟可以**为Si个同种细胞(Si为正整数)。现在他需要选取某种细胞的一个放进培养皿,让其自由**,进行培养。一段时间以后,再把培养皿中的所有细胞平均分入 M 个试管,形成 M 份样本,用于实验。Hanks 博士的试管数 M 很大,普通的计算机的基本数据类型无法存储这样大的M 值,但万幸的是,M 总可以表示为 m1的 m2次方,即M = m1^m2,其中 m1,m2均为基本数据类型可以存储的正整数。

注意,整个实验过程中不允许分割单个细胞,比如某个时刻若培养皿中有 4 个细胞,Hanks 博士可以把它们分入 2 个试管,每试管内 2 个,然后开始实验。但如果培养皿中有 5 个细胞,博士就无法将它们均分入 2 个试管。此时,博士就只能等待一段时间,让细胞们继续**,使得其个数可以均分,或是干脆改换另一种细胞培养。

为了能让实验尽早开始,Hanks 博士在选定一种细胞开始培养后,总是在得到的细胞“刚好可以平均分入 M 个试管”时停止细胞培养并开始实验。现在博士希望知道,选择哪种细胞培养,可以使得实验的开始时间最早。

 

自创了一种奇怪的做法,结果WA30

#include<iostream>
#define inf (1<<25)
#define reg register
#define int long long
using namespace std;
int n,m1,m2;
int ans=inf,cnt;
int s[10005],fac[30005][2];
bool check(int x){
	for(int i=1;i<=cnt;i++)
		if(x%fac[i][0]!=0) return false;
	return true;
}
int Ceil(int a,int b){
	if(a%b==0) return a/b;
	else return a/b+1;
}
signed main(){
    cin>>n>>m1>>m2;
    int tmp=m1;
    for(int i=1;i<=n;i++)
    	cin>>s[i];
    for(int i=2;i*i<=tmp;i++){
    	if(tmp%i==0){
    		fac[++cnt][0]=i;
    		int t=0;
    		while(tmp%i==0) tmp/=i,t++;
    		fac[cnt][1]=t;
		}
	}
	if(tmp!=1) fac[++cnt][0]=tmp,fac[cnt][1]=1;
    for(int i=1;i<=n;i++){
    	if(check(s[i])){
    		tmp=s[i];
    		int val=-1;
    		for(int j=1;j<=cnt;j++){
    			int t=0;
    			while(tmp%fac[j][0]==0) tmp/=fac[j][0],t++;
    			val=max(val,Ceil(fac[j][1],t));
			}
			ans=min(ans,val);
		}
	}
    if(ans==inf) cout<<-1;
    else cout<<ans;
    return 0;
}

 

汪恺恒在2021-08-08 10:32:07追加了内容

发现一个错误,现在WA70

#include<iostream>
#define inf (1<<25)
#define reg register
#define int long long
using namespace std;
int n,m1,m2;
int ans=inf,cnt;
int s[10005],fac[30005][2];
bool check(int x){
	for(int i=1;i<=cnt;i++)
		if(x%fac[i][0]!=0) return false;
	return true;
}
int Ceil(int a,int b){
	if(a%b==0) return a/b;
	else return a/b+1;
}
signed main(){
    cin>>n>>m1>>m2;
    int tmp=m1;
    for(int i=1;i<=n;i++)
    	cin>>s[i];
    for(int i=2;i*i<=tmp;i++){
    	if(tmp%i==0){
    		fac[++cnt][0]=i;
    		int t=0;
    		while(tmp%i==0) tmp/=i,t++;
    		fac[cnt][1]=t*m2;
		}
	}
	if(tmp!=1) fac[++cnt][0]=tmp,fac[cnt][1]=1;
    for(int i=1;i<=n;i++){
    	if(check(s[i])){
    		tmp=s[i];
    		int val=-1;
    		for(int j=1;j<=cnt;j++){
    			int t=0;
    			while(tmp%fac[j][0]==0) tmp/=fac[j][0],t++;
    			val=max(val,Ceil(fac[j][1],t));
			}
			ans=min(ans,val);
		}
	}
    if(ans==inf) cout<<-1;
    else cout<<ans;
    return 0;
}

 


0
已采纳
李奕歌
李奕歌
初级天翼
初级天翼

函数:

void div(){
    memset(prime,0,sizeof(prime));
    for(int i=2;i<=m1;i++){
        while(m1%i==0){
            prime[i]++;
            m1/=i;
            maxu=i;
        }
        prime[i]*=m2;
    }
}

核心:

if(m1==1){
        printf("0");
        return 0;
    }
    div();
    ans=2147483647;
    for(int i=0;i<n;i++){
        scanf("%d",&num);
        t=-1;
        for(int i=2;i<=maxu;i++){
            if(prime[i]>0){

                    int cur=0;
                    while(num%i==0){
                        cur++;
                        num/=i;
                    }
                    if(cur==0){
                        t=-1;
                        break;
                    }
                    t=max(t,prime[i]%cur==0?prime[i]/cur:prime[i]/cur+1);

            }
        }
        if(t!=-1){
            ans=min(ans,t);
        }
    }
    printf("%d",ans<2147483647?ans:-1);

 

0
我要回答