一名苦逼的OIer,想成为ACMer

Iowa_Battleship

洛谷1069 细胞分裂

原题链接

其实就是分解质因数。
\(m_1\)分解质因数,注意每个质因数的个数要乘上\(m_2\),设个数为\(a_j\)
而要使得\(m_1 ^ {m_2} | S_i ^ k\),显然要求\(S_i\)的质因数包含\(m_1\)的质因数,至于个数的要求,让\(k\)足够大即可。
因此对每一个\(S_i\)\(m_1\)的质因数去试除,若全部能除尽,那这个细胞肯定是可行的。然后计算出对于每个质因数在\(S_i\)中拥有的个数\(b_j\),那么对于这个细胞达到要求的所需时间为\(\max\{ \left\lceil \dfrac{a_j}{b_j} \right\rceil \}\)
最后的答案就是对每个可达到要求的细胞所需时间取\(\min\)

#include<cstdio>
#include<cmath>
using namespace std;
const int N = 110;
int pr[N], S[N], l;
inline int re()
{
	int x = 0;
	char c = getchar();
	bool p = 0;
	for (; c < '0' || c > '9'; c = getchar())
		p |= c == '-';
	for (; c >= '0' && c <= '9'; c = getchar())
		x = x * 10 + c - '0';
	return p ? -x : x;
}
inline int maxn(int x, int y) { return x > y ? x : y; }
inline int minn(int x, int y) { return x < y ? x : y; }
int main()
{
	int i, j, x, s, k, n, m_1, m_2, an = 1e9;
	n = re(); m_1 = re(); m_2 = re();
	for (i = 2; i * i <= m_1; i++)
		if (!(m_1 % i))
		{
			for (pr[++l] = i; !(m_1 % i); S[l]++, m_1 /= i);
			S[l] *= m_2;
		}
	if (m_1 > 1)
	{
		pr[++l] = m_1;
		S[l] = m_2;
	}
	for (i = 1; i <= n; i++)
	{
		x = re();
		for (j = 1; j <= l; j++)
			if (x % pr[j])
				break;
		if (j <= l)
			continue;
		for (j = 1, k = 0; j <= l; j++)
		{
			for (s = 0; !(x % pr[j]) && s <= S[j]; s++, x /= pr[j]);
			k = maxn(k, ceil(S[j] * 1.0 / s));
		}
		an = minn(an, k);
	}
	printf("%d", an == 1e9 ? -1 : an);
	return 0;
}

posted on 2019-02-16 13:53  Iowa_Battleship  阅读(163)  评论(0编辑  收藏  举报

导航