P1463 [SDOI2005]反素数ant
P1463 [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
一道水题 就是找最大的反素数
我们先建一棵搜索树
以12为例
从根节点到每个叶子节点路径上的数乘起来就是12的约数
我们可以按照这个思路来找反素数 具体解释见代码
这个题n<=2*10^9 不会超过int
log2(2*10^9)大约在30左右
所以我们每一个素数最多递归30层
记录当前到了第几个素数 这个素数用了几遍 产生几个约数 当前的now是多少
1 #pragma GCC optimize(2) 2 #include <cstdio> 3 #include <cctype> 4 5 typedef long long LL; 6 7 LL ans; 8 9 #define Inline __attri\ 10 bute__( ( optimize( "-O2" ) ) ) 11 12 int n,Now; 13 14 int prime[20]={0,2,3,5,7,11,13,17,19,23,29}; 15 16 Inline void DFS(int num,int Np,LL now) { 17 if(now>n) return;//如果当前数now大于n 就返回 最优性剪枝 18 if(Np>Now||Np==Now&&now<ans) {Now=Np;ans=now;} 19 // 如果当前约数个数大于目前全局最优解 或者约数个数等于全局最优解但是当前数要大于目前全局最优解 就更新 20 LL t=1,s=0;// s为当前素数使用了几次 t则就是当前素数使用了s次产生的约数 21 for(int i=1;i<=30;++i) { 22 t*=prime[num]; 23 ++s; 24 if(now*t>n) return;// 当前数now乘约数t产生的数大于n 说明当前搜索方向无法产生解 25 DFS(num+1,Np*(s+1),now*t); 26 } 27 } 28 29 int hh() { 30 scanf("%d",&n); 31 DFS(1,1,1); 32 printf("%lld\n",ans); 33 } 34 35 int sb=hh(); 36 int main(int argc,char**argv) {;}
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现