洛谷 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;
}