退退退! 题解

题目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;
}
posted @ 2024-08-01 16:07  Firra3500  阅读(7)  评论(0编辑  收藏  举报