n的约数/反素数-dfs

n的约数 (nowcoder.com)

Problem

求1-n内约数最多的数的约数是多少个。

Solution

有唯一分解定理可知 a = p1^{c1}*p2^{c2}*...*pm^{cm}

a的因子个数为 (1+c1)*(1+c2)*...*(1+cm)

而要a的因子数更多,那么质因子越小对于的指数越大,也就是说c1 >= c2 >=c3 >=...>=cm

然后从质因子2开始dfs,寻找最大的因子个数。

Code

#include <bits/stdc++.h>
#define ll long long
#define pir pair<int,int>
const int N = 1e6+7;
const int mod = 1e9+7;
const ll ds = 1e15;
const double eps = 1e-8;

using namespace std;

int pr[55] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,51,53};//17
ll ans = 0,n;
void dfs(ll sum,int pos,int lim,ll cnt){//n,质因子的下标,前一个质因子个数对后一个质因子的约数,质因子个数
    //cout << pos << endl;
    if(pos > 15) return;
    ans = max(ans,cnt);
    for(int i = 1; i <= lim; i++){
        if(pr[pos] > n/sum) break;
        sum *= pr[pos];//相当于乘上pr[pos]^i
        dfs(sum,pos+1,i,cnt*(i+1));
    }
}

void solve(){
    cin >> n;
    ans = 0;
    dfs(1ll*1,0,60,1);
    cout << ans << endl;
}
int main(){
    int t;
    cin >> t;
    while(t--)
        solve();
    //system("pause");
    return 0;
}

反素数

https://ac.nowcoder.com/acm/problem/19967

Problem

求不超过n的反素数。

反素数定义:所有小于x的数的因子个数都小于x的因子个数。

注意是小于,不是小于等于。

Solution

思路同上。也就是要求含有因子个数最多的数是哪个,当相同的时候取更小的数,因为是小于,没有等于。

#include <bits/stdc++.h>
#define ll long long
#define pir pair<int,int>
const int N = 1e6+7;
const int mod = 1e9+7;
const ll ds = 1e15;
const double eps = 1e-8;

using namespace std;

int pr[55] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,51,53};//17
ll ans = 0,n,anss = 0;
void dfs(ll sum,int pos,int lim,ll cnt){
    //cout << pos << endl;
    if(cnt > ans || (cnt == ans && anss > sum)){//相等取更小的
        ans = cnt;
        anss = sum;
    }
    if(pos > 15) return;
    for(int i = 1; i <= lim; i++){
        if(pr[pos] > n/sum) break;
        sum *= 1ll*pr[pos];
        dfs(sum,pos+1,i,cnt*(i+1));
    }
}

void solve(){
    cin >> n;
    ans = 0;
    dfs(1ll*1,0,60,1);
    cout << anss << endl;
}
int main(){
    // int t;
    // cin >> t;
    // while(t--)
        solve();
    //system("pause");
    return 0;
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值