zoukankan      html  css  js  c++  java
  • 洛谷 1463[SDOI2005] 反素数ant

    题目描述

    对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。

    如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数。例如,整数1,2,4,6等都是反质数。

    现在给定一个数N,你能求出不超过N的最大的反质数么?

    输入输出格式

    输入格式:

    一个数N(1<=N<=2,000,000,000)。

    输出格式:

    不超过N的最大的反质数。

    输入输出样例

    输入样例#1:
    1000
    输出样例#1:
    840

    题解:
    即求一个1到n以内的数,使得这个数有最多的约数。如果有多解,只找最小的那个。
    把一个数分解质因数,假设是p1^q1 * p2^q2 * p3^q3……*pi^qi,那么约数个数是(q1+1)*(q2+1)*(q3+1)……*(qi+1)。
    根据数据范围可以知道,只需要用到前12个质数,那么可以预处理出前几个质数,然后暴搜即可。
    然后有一个优化,对于两个数,它们分解质因数之后是a^q1*b^q2和a^q2*b^q1,满足a<b,q1<q2,这两个数的约数个数都是(q1+1)(q2+1),但是第一个数小,所以我们应该取第一个数。
    所以我们可以加一个剪枝:前一个质数的指数一定大等于后一个质数的指数。
    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #define lo long long
    #define inf 100000000
    using namespace std;
    const lo pri[14]={0,2,3,5,7,11,13,17,19,23,29,31,37};
    lo read()
    {
    	lo ans=0,f=1;char ch=getchar();
    	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    	while(isdigit(ch)) {ans=ans*10+ch-'0';ch=getchar();}
    	return ans*f;
    }
    lo ma=-1,num,n;
    void solve(lo sum,lo yin,int cnt,int z)
    {
    	if(sum>n) return;
    	if(yin>ma||(yin==ma&&sum<num)) 
    	{
    		num=sum;
    		ma=yin;
    	}
    	lo zc=pri[++cnt],nz=1;
    	while(sum*zc<n&&nz<z)
    	{
    		nz++;
    		sum*=zc;
    		solve(sum,yin*nz,cnt,nz);
    	}
    }
    int main()
    {
    	n=read();
    	solve(1,1,0,inf);
    	printf("%lld",num);
    	return 0;
    }
  • 相关阅读:
    [转]为什么匿名内部类参数必须为final类型
    [转]软件开发规范—模块开发卷宗(GB8567——88)
    [转]概要设计与详细设计的区别
    [转]解析UML建模语言中的UML图分类、 UML各种图形及作用
    python mysql插入中文乱码
    pycharm mysql数据源配置、SQL方言配置
    pycharm批量查找替换,正则匹配
    python第三方库安装
    什么是Vagrant
    python读写excel文件
  • 原文地址:https://www.cnblogs.com/charlotte-o/p/7502448.html
Copyright © 2011-2022 走看看