西安电子科技大学第16届程序设计竞赛网络同步赛 G-小国的复仇

本文介绍了一个关于获取特定数量小国的算法挑战。通过分解质因数的方法找到获得目标数量所需的最小魔法次数,实现高效求解。
链接: https://www.nowcoder.com/acm/contest/107/G
来源:牛客网

题目描述

众所周知,汀老师是XDUACM实验室最优秀的人,无论是学习还是打游戏。今天他突然想到一个好玩的游戏。规则是这样的,在游戏中他要得到n个小国,初始的时候小国和小杰各有1个。经过了很久的修炼,汀老师学会了两种魔法,他每次可以动用自己的智慧来使用魔法。

第一个魔法:(小杰变小国)可以将自己的智慧复制和当前小杰一样数量的小国出来;

第二个魔法:(小国大爆发)可以将当前的小杰变成和小国的数量一样,然后小国的数量加倍!

因为汀老师的智力是无限多的,他不关心花掉的智力大小。但是好学的汀老师想尽快得到n个小国,使得能有更多的时间去读paper和打比赛。他想问问你,最少需要使用多少次魔法可以得到n个小国。

得到了n个小国后,汀老师去学习,但是小国们基因突变在电脑里越来越多!他们来组织汀老师学习,现在告诉汀老师我要得到更多的同伴!

输入描述:

多组数据,第一行一个正整数T(T<=100000)表示数据组数。
接下来T行,每行一个正整数n(n<=10^6)。

输出描述:

对于每组数据输出一个整数,表示得到n个小国汀老师最少需要使用多少次膜法。

题解:
写了一发dfs超时啦,打表找规律发现n为素数时答案为n-1,否则n分解为两个因子的答案数相加。
代码:
#include<bits/stdc++.h>
using namespace std;
const int inf=1e9;
bool is[1000006];
int p[1000006],tol=0;
int a[1000006];
void init()
{
    for(int i=2;i<1000006;i++)
    {
        if(!is[i])
        {
            p[tol++]=i;
            for(int j=i+i;j<1000006;j+=i)is[j]=1;
        }
    }
}
int main()
{
    init();int T;scanf("%d",&T);
    a[1]=0;
    for(int i=2;i<=1000000;i++)
    {
        if(!is[i])a[i]=i-1;
        else
        {
            int id=0;
            for(int j=p[0]; ;j=p[++id])
            {
                if(i%j==0)
                {
                    a[i]=a[i/j]+a[i/(i/j)];break;
                }
            }
        }
    }
    while(T--)
    {
        int n;scanf("%d",&n);printf("%d\n",a[n]);
    }
    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值