1. 程式人生 > >BZOJ 1053 HAOI2007 反素數

BZOJ 1053 HAOI2007 反素數

因子 scan logs 原理 scanf cnblogs max 說明 code

1.
一個數的約數個數=所有素因子的冪次+1的乘積
這個直觀的理解就是 2^x*3^y 我能拆出來
2^0*3^0
2^0*3^1
2^0*3^2
……
2^1*3^0
2^1*3^1
……
2^2*3^0
……
2^x*3^0
……
2^x*3^y
根據乘法原理 2一共有x+1個冪 3有y+1個冪 所以就是(x+1)*(y+1)

2.
寫一個暴力跑程序會發現一個2000000000以內的數字不會有超過12個素因子

3.
較小的數的冪次一定大於等於較大的數的冪次

之後就是赤裸裸的DFS暴搜了

 1 #include <cstdio>
 2
#include <algorithm> 3 4 typedef long long ll; 5 ll n; 6 int ans=1,num=1; 7 8 ll Max,last; 9 //1的確不是質數 但是x^0需要用到 10 int prime[15]={1,2,3,5,7,11,13,17,19,29,31}; 11 12 void dfs(int dep,ll Num,int tot,int limit){ 13 if(dep==12){ 14 //當前值大於記錄值 並且約數也比上次那個多 15 if
(Num > Max && tot> last){ 16 Max = Num; 17 last = tot; 18 } 19 //當前值小於記錄值 並且約數也比上次那個多 記錄值不合法 20 /*這裏這個“= ”特別說明一下 21 g(x)>g(i) 0<i<x 22 當前的值是i 比 x 小滿足條件,但是如果g(i)<g(x)或者 g(i)=g(x)都不合法 23
*/ 24 if(Num <= Max && tot >= last){ 25 Max = Num; 26 last = tot; 27 } 28 return; 29 } 30 int mul = 1; 31 for(int i=0;i<=limit;++i){ 32 dfs(dep+1,Num*mul,tot*(i+1),i); 33 mul*=prime[dep]; 34 if(Num*mul>n) break; 35 } 36 } 37 38 int main(){ 39 scanf("%d",&n); 40 dfs(1,1,1,20); 41 printf("%lld\n",Max); 42 return 0; 43 }

BZOJ 1053 HAOI2007 反素數