• 反素数——Antiprime


    描述
    如果一个大于等于 1 的正整数 n ,满足所有小于 n 且大于等于 1 的所有正整数的约数个数都小于 n 的约数个数,则 n 是一个 Antiprime 数。譬如:1,2,4,6,12,24 ,它们都是 Antiprime 数。
    请你计算不大于 n 的最大 Antiprime 数。
    输入
    一行一个正整数 n 。
    输出
    只包含一个整数,即不大于 n 的最大 Antiprime 数。
    样例输入
    1000
    样例输出
    840
    提示
    对于 10%的数据,1≤n≤10^3
    对于 40%的数据,1≤n≤10^6
    对于 100%的数据,1≤n≤2×10^9

    首先来讲一下正解吧

    很容易发现

    不大于n的最大的antiprime一定是1~n中质因子最多的数中最小的那一个

    又因为n<=2e9n<=2e92357111317192329>2e92*3*5*7*11*13*17*19*23*29>2e9

    所以说1~n的最大的antiprime的质因子不会超过10个

    而且每一个质因子的指数一定是递减的

    如果有一个质因子的指数比前面的大,那么把他们两个的指数交换就能得到一个更小的约数个数相同的数

    所以说指数一定递减

    那么我们可以直接考虑深搜

    枚举每个质因子的指数

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
        char ch=getchar();
        int res=0;
        while(!isdigit(ch))ch=getchar();
        while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
        return res;
    }
    #define ll long long
    const ll inc[12]={1,2,3,5,7,11,13,17,19,23,29,31};
    ll n;
    ll minn=1e9,mnum=-100000;
    void dfs(ll now,int k,ll num,int mst){
        if(mnum<num){
            minn=now,mnum=num;
        }
        if(mnum==num&&minn>now){
            minn=now,mnum=num;
        }//
        if(k>10)return;
        ll p=now;
        for(int i=1;i<=mst;i++){
            if(p*inc[k]>n)break;
            p=p*inc[k];
            dfs(p,k+1,num*(i+1),i);
        }
    }
    int main(){
        n=read();
        dfs(1,1,1,31);
        cout<<minn<<'
    ';
    }
    

    当然我们也会发现反素数的个数其实是很少的

    那么我们也可以考虑打表

    枚举出2e9以内的所有反素数

    直接查找就可以了

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    ll antip[1000] = {1396755360,1102701600,735134400,698377680,551350800,367567200,294053760,245044800,183783600,147026880,122522400,110270160,73513440,61261200,43243200,36756720,32432400,21621600,17297280,14414400,10810800,8648640,7207200,6486480,4324320,3603600,2882880,2162160,1441440,1081080,720720,665280,554400,498960,332640,277200,221760,166320,110880,83160,55440,50400,45360,27720,25200,20160,15120,10080,7560,5040,2520,1680,1260,840,720,360,240,180,120,60,48,36,24,12,6,4,2,1};//当然这里并没有1000个,只是开大数组而已
    ll n;
    int main(){
    	cin>>n;
    	for(int i=999;i>=0;i--){
    		if(antip[i]>n&&antip[i+1]<n){
    			cout<<antip[i+1];
    			return 0;
    		}
    	}
    	cout<<antip[0];
    }
    
  • 相关阅读:
    python的元类
    中国的互联网:草根与精英
    PEP8中文翻译
    一些重要的算法
    tornado模板语法
    C#l类与对象
    sql_ 存储过程
    SQL_触发器
    SQL_事务处理
    C#_方法
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366451.html
Copyright © 2020-2023  润新知