洛谷 P1069 细胞分裂

洛谷 P1069 细胞分裂

Description

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

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

    注意,整个实验过程中不允许分割单个细胞

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

Input

  • 第一行,有一个正整数 N,代表细胞种数。

    第二行,有两个正整数 m1,m2,以一个空格隔开,即表示试管的总数

    第三行有 N 个正整数,第 i 个数 Si表示第 i 种细胞经过 1 秒钟可以分裂成同种细胞的个数。

Output

  • 一个整数,表示从开始培养细胞到实验能够开始所经过的最少时间(单位为秒)。

    如果无论Hanks博士选择哪种细胞都不能满足要求,则输出整数−1。

Sample Input

1
2 1
3

2
24 1
30 12

Sample output

-1

2

题解:

  • 数论——素数筛法。
  • 具体就是一个分解质因数。
  • 思路不难,细节很多。
  • 思路就是先将试管数分解质因数,将每个质因数的个数存在数组a里。
  • 然后对于每个给出的细胞,拿它去除a里的质数,假设能除tmp下。然后拿tmp跟a[这个质数]相比。大于等于就没啥,小于的话这个细胞就需要扩大。然后算出需要扩大的幂x
  • 每个细胞与a里的质数相除时,最终的幂要取最大的
  • 最后ans等于每个细胞的幂取最小值
#include <iostream>
#include <cstdio>
#include <map>
#include <cmath>
#define maxn 10005
#define inf 0x7fffffff
using namespace std;

int n, m1, m2, cnt, ans = inf;
int a[maxn];
map<int, int> mp;

int logg(int x, int y)
{
    int g = 0;
    while(x % y == 0) x /= y, g++;
    return g;
}

int main()
{
    freopen("P1069.in", "r", stdin);
    freopen("P1069.out", "w", stdout);
    
    cin >> n >> m1 >> m2;
    if(m1 == 1) {cout << 0; return 0;} //特判
    int m11 = m1;
    for(int i = 2; i <= m1; i++)
    {
        int flag = 0, g = 0;
        while(m1 % i == 0)
        {
            if(!flag) flag = 1, a[++cnt] = i;
            m1 /= i, g++;
        }
        if(flag) mp[a[cnt]] = g * m2;
    }
    m1 = m11;
    for(int i = 1; i <= n; i++)
    {
        int t, flag = 0, sum = 0;
        scanf("%d", &t);
        for(int j = 1; j <= cnt; j++)
        {
            int num = a[j];
            int tot = logg(t, num);
            if(!tot) {flag = 1; break;}
            if(tot < mp[num])
            {
                int x = (int)ceil((double)mp[num] / (double)tot);
                sum = max(sum, x);
            }
        }
        if(!flag) ans = min(ans, sum);
    }
    if(ans == inf) cout << -1;
    else cout << ans;
    return 0;
}

转载于:https://www.cnblogs.com/BigYellowDog/p/11169093.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值