退退退! 题解
题目id:20295
题目描述
最近的小镇不太平,一到午夜就会有僵尸出没!
小镇百姓找上你,请你来镇压这只僵尸。僵尸的体力可以看作一个整数\(n\),你需要用若干张镇妖符来压制僵尸,一张镇妖符可以看作一个整数\(x\)。假设你用了\(m\)张镇妖符,则它们的压制力为\(x_1×x_2×...×x_m\),既\(\prod\limits_{i=1}^{m}{x_i}\)。
这些镇妖符需要满足以下条件:
- \(x_i=p^k\),其中\(p\)为素数,\(k\)为正整数。
- \(\prod\limits_{i=1}^{m}{x_i}\)能够整除\(n\)
- \(x_i\)互不相同
你希望用尽可能多的镇妖符来压制僵尸,请问最多可以用多少张镇妖符。
解题思路
由于第一条\(x_i=p^k\),所以该题考查分解质因数。
枚举\(n\)的每个因子出现的次数,从\(1\)开始枚举\((1\)最小题目要求尽量多,而且第二条要求\(x_i\)互不相同\()\),直到出现次数用完为止,照这样的策略可以用更多镇妖符来实现同样的压制力。
假设\(cnt\)为质因子\(i\)出现的次数,\(ans\)为当前答案,则片段如下:
for(int j=1;j<=cnt;++j)
{
++ans;
cnt-=j;
}
如果因子枚举完后\(n\)依然大于\(1\),则答案加\(1(\)还需要一张镇妖符才能让压制力整除\(n)\)
输出答案即可。
AC Code
#include<bits/stdc++.h>
#define N 1000007
#define INF 1000000007
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define IOS ios::sync_with_stdio(0),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
LL n,ans;
int main()
{
IOS;
cin>>n;
for(LL i=2;i<=n/i;++i)
if(n%i==0)
{
LL cnt=0;
while(n%i==0)
{
++cnt;
n/=i;
}
for(int j=1;j<=cnt;++j)
{
++ans;
cnt-=j;
}
}
if(n>1)
++ans;
cout<<ans;
return 0;
}