hdu4937 Lucky Number
比较简单的数论题。
把n分别减去3 4 5 6,剩下的为tn。
求出tn的所有约数,尝试所有约数是否满足基的条件即可。这样复杂度只有O(sqrt(n))。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define Maxn 1100000
int vt[Maxn],tp;
long long pri[Maxn];
long long fac[1010];
int cnt[1010];
long long ttn;
int totf;
long long ans;
void sieve(int n){
int m=(int) sqrt(n+0.5);
memset(vt,0,sizeof(vt));
tp=0;
int i,j;
for(i=2;i<=n;++i)if (!vt[i]){
pri[++tp]=i;
//printf("%d\n",i);
if (i>m) continue;
for(j=i*i;j<=n;j+=i){
vt[j]=1;
}
}
//printf(" tp=%d\n",tp);
}
void check(long long ff,long long mibase){
long long tmp=ttn;
int fl=0;
tmp=tmp/ff;
long long t2;
while(tmp){
t2=tmp%ff;
if (t2<3||t2>6) return;
tmp=tmp/ff;
}
ans++;
}
void dfs(int now,long long ff,long long mibase){
if (now==totf){
if (ff<mibase) return;
check(ff,mibase);
return;
}
int i;
long long k=1;
for(i=0;i<=cnt[now+1];++i){
dfs(now+1,ff*k,mibase);
k*=fac[now+1];
}
}
void work(long long n,long long mibase){
int i;
memset(cnt,0,sizeof(cnt));
totf=0;
long long on=n;
for(i=1;i<=tp;++i){
if (pri[i]*pri[i]>on) break;
if (n%pri[i]==0) {
fac[++totf]=pri[i];
while(n%pri[i]==0){
n/=pri[i];
++cnt[totf];
}
}
}
if (n!=1) {
fac[++totf]=n;
cnt[totf]=1;
}
dfs(0,1,mibase);
}
int main(){
int cas,tcas,i;
long long n;
scanf("%d",&cas);
sieve(1001000);
for(tcas=1;tcas<=cas;++tcas){
scanf("%I64d",&n);
if (n>=3&&n<=6) {
printf("Case #%d: -1\n",tcas);
continue;
}
if (n<3) {
printf("Case #%d: 0\n",tcas);
continue;
}
ans=0;
long long mibase;
for(i=3;i<=6;++i){
long long tn=n-i;
mibase=i+1;
ttn=tn;
work(tn,mibase);
}
printf("Case #%d: %I64d\n",tcas,ans);
}
return 0;
}