您的位置:首页 > 其它

#166-[分解质因数]细胞分裂

2018-11-05 13:57 162 查看
版权声明:反正也没有人会转,下一个 https://blog.csdn.net/drtlstf/article/details/83748336

Description

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 个试管”时停止细胞培养并开始实验。现在博士希望知道,选择哪种细胞培养,可以使得实验的开始时间最早。

Input

第一行有一个正整数 N,代表细胞种数。
第二行有两个正整数 m1,m2,以一个空格隔开,m1^m2 即表示试管的总数M。
第三行有 N 个正整数,第i 个数Si 表示第i 种细胞经过1 秒钟可以分裂成同种细胞的个数。

Output

为一个整数,表示从开始培养细胞到实验能够开始所经过的最少时间(单位为秒)。
如果无论 Hanks 博士选择哪种细胞都不能满足要求,则输出整数-1。

Sample Input

[code]输入样例1:
1
2 1
3
输入样例2:
2
24 1
30 12

Sample Output

[code]输出样例1:
-1
输出样例2:
2

HINT

 

【输入输出样例1说明】

经过1秒钟,细胞分裂成3个,经过2秒钟,细胞分裂成9个,……,可以看出无论怎么分裂,细胞的个数都是奇数,因此永远不能分入2个试管。

【输入输出样例2说明】
第1种细胞最早在3秒后才能均分入24个试管,而第2种最早在2秒后就可以均分(每试管144/(24^1)=6个)。故实验最早可以在2秒后开始。


【数据范围】
对于50%的数据,有 m1^m2 ≤30000。

对于所有的数据,有1≤N≤10000,1≤m1≤30000,1≤m2≤10000,1≤Si≤2,000,000,000。

分解质因数,考试时凭直觉.

那么是什么道理呢?

首先,把m1分解,假设为A1,A2,......,An

那么m需要的质因数就是m2个A1,m2个A2,......,m2个An.
然后分解每一个细胞的分裂量,找到能把每一项质因数都大于等于M所需要的质因数

当然,如果M需要的质因数有任何一项细胞的分裂量没有的话,肯定不能用这种细胞.

[code]#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>

#define SIZE 30010
#define INF 2e+09

using namespace std;

vector<int> v, cnt;

int main(void)
{
int m1, m2, n, temp, i, j, x, count, res = INF, t;
bool flag;

scanf("%d%d%d", &n, &m1, &m2);
temp = m1;
for (i = 2; i <= m1; ++i) // 将M分解质因数
{
count = 0;
while (temp % i == 0)
{
++count;
temp /= i;
}
if (count)
{
v.push_back(i);
cnt.push_back(count * m2);
}
}
for (i = 1; i <= n; ++i)
{
scanf("%d", &x);
temp = x;
flag = false;
t = 0;
for (j = 0; j < v.size(); ++j)
{
if (temp % v[j]) // M需要的因数没有,不能用
{
flag = true;
break;
}
count = 0;
while (temp % v[j] == 0)
{
++count;
temp /= v[j];
}
t = max(t, int (ceil(cnt[j] / double (count)))); // 找到使用这种细胞要的时间
}
if (flag)
{
t = INF;
}
res = min(res, t);
}

if (res < INF) // 如果找到了一种可行解就输出最小时间
{
printf("%d", res);
}
else // 否则,输出-1
{
printf("-1");
}

return 0;
}

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: