[ HDU 5878 ] I Count Two Three
考虑极端,1e9就是2的30次方,3的17次方,5的12次方,7的10次方。
而且,不超过1e9的乘积不过5000多个,于是预处理出来,然后每次二分找就可以了。
1 /* 2 TASK:I Count Two Three 2^a*3^b*5^c*7^d的最小的大于等于n的数是多少 3 LANG:C++ 4 URL:http://acm.hdu.edu.cn/showproblem.php?pid=5878 5 */ 6 #include <iostream> 7 #include <algorithm> 8 #include <cstdio> 9 #include <cstring> 10 #define ll long long 11 using namespace std; 12 const int N=32; 13 const ll M=1e9+1; 14 int tw,th,fi,se,t,n; 15 ll two[N]={1},three[N]={1},five[N]={1},seven[N]={1}; 16 ll ans[7000],cnt; 17 int main() { 18 for(int i=1;two[i-1]<M;i++,tw++) 19 two[i]=two[i-1]*2; 20 for(int i=1;three[i-1]<M;i++,th++) 21 three[i]=three[i-1]*3; 22 for(int i=1;five[i-1]<M;i++,fi++) 23 five[i]=five[i-1]*5; 24 for(int i=1;seven[i-1]<M;i++,se++) 25 seven[i]=seven[i-1]*7; 26 27 for(int i=0;i<tw;i++) 28 for(int j=0;three[j]*two[i]<M&&j<th;j++) 29 for(int k=0;five[k]*three[j]*two[i]<M&&k<fi;k++) 30 for(int g=0;seven[g]*five[k]*three[j]*two[i]<M&&g<se;g++) 31 ans[cnt++]=two[i]*three[j]*five[k]*seven[g]; 32 33 sort(ans,ans+cnt); 34 35 scanf("%d",&t); 36 while(t--){ 37 scanf("%d",&n); 38 printf("%lld\n",ans[lower_bound(ans,ans+cnt,n)-ans]); 39 } 40 }