现在的位置: 首页 > 综合 > 正文

lightoj 1276 Very Lucky Numbers

2018年02月21日 ⁄ 综合 ⁄ 共 967字 ⁄ 字号 评论关闭

题目大意 : lucky number是指只含4和7的数字。very lucky number是指lucky number 和能有several个lucky number做乘积得到的数。询问一些区间[A,B](A,B<=1e12)之间very lucky number 的数量。

思路: 预先处理出所有的8000+个lucky number ,然后对这些数dfs得到范围内的所有very lucky number 。然后对于每个区间二分即可。

lucky number 只有2^12=4096个。

然后dfs。碰到乘起来超过范围的直接结束搜索。

接着利用超级屌的二分搞定。。

vector<ll> T;
void dfs(int d,ll dig) {
    if(d>12)return;
    T.pb(dig);
    dfs(d+1,dig*10+4);
    dfs(d+1,dig*10+7);
}
int tmp;
void dfs2(ll dig,int t) {
    if(dig!=1)T.pb(dig);
    for(int i=t; i<tmp; i++) {
        if(T[i]<=1000000000000LL/dig)dfs2(dig*T[i],i);
        else break;
    }
}
int lower(ll x) {
    if(x<T[0])return 0;
    if(x>=T[T.size()-1])return T.size();
    int l=0,r=T.size()-1;
    int mid;
    while(l<=r) {
        mid=(l+r)>>1;
        if(T[mid]==x)return mid+1;
        if(x>T[mid])l=mid+1;
        else r=mid-1;
    }
    return min(r,mid)+1;
}
int main() {
    T.clear();
    dfs(1,4);
    dfs(1,7);
    tmp=T.size();
    sort(T.begin(),T.end());
    dfs2(1,0);
    sort(T.begin(),T.end());
    T.erase(unique(T.begin(),T.end()),T.end());
    int TT;
    scanf("%d",&TT);
    for(int tt=1; tt<=TT; tt++) {
        ll a,b;
        scanf("%lld%lld",&a,&b);
        printf("Case %d: %d\n",tt,lower(b)-lower(a-1));
    }

    return 0;
}

抱歉!评论已关闭.