zoukankan      html  css  js  c++  java
  • Codeforces Beta Round #91 (Div. 1 Only) A. luckSum(区间分块求解)

    这道题的主要解法在对1~100000000 中的luckNumber进行分块求和;

    例如, luckSum[0] = Sum[1,4]  luckSum[1] = Sum[5,7] luckSum[2] = Sum[8,44] ......................

    然后根据l,r 的区间跨度来求和;

    所在区间用一个int findUnder(int l)来求取;

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    typedef long long ll;
    
    const int maxn = 1e9;
    ll luckNumber[1500][2];
    ll luckSum[1500];
    
    void init(){
        int cnt=2;
        long long num;
        queue<long long> que; 
        
        luckNumber[0][0]=1;
        luckNumber[0][1]=4;
        luckNumber[1][0]=5;
        luckNumber[1][1]=7;
        
        que.push(4);
        que.push(7);
        
        while(!que.empty()){
            num = que.front();
            que.pop();
            
            if(num*10+4<=maxn) luckNumber[cnt][0] = luckNumber[cnt-1][1]+1,luckNumber[cnt++][1] = num*10+4,que.push(num*10+4);
            else break;
            
            if(num*10+7<=maxn) luckNumber[cnt][0] = luckNumber[cnt-1][1]+1,luckNumber[cnt++][1] = num*10+7,que.push(num*10+7);
            else break;
            
        }
        luckNumber[cnt][0]=luckNumber[cnt-1][1]+1;
        luckNumber[cnt][1]=4444444444;
        
        for(int i=0;i<cnt;i++){
            luckSum[i] = (luckNumber[i][1]-luckNumber[i][0]+1)*luckNumber[i][1];
            //cout<<luckSum[i]<<endl;
        }
        //cout<<cnt<<endl;
            
    }
    
    int findUnder(int l){
        
        for(int i=0;i<=1022;i++){
            if(l<=luckNumber[i][1]&&l>=luckNumber[i][0]) return i;
        }
        
    }
    
    int main(){
        init(); 
        int l,r,lSize,rSize;
        ll sum;
        scanf("%d%d",&l,&r);
        
        lSize = findUnder(l);
        rSize = findUnder(r);
        sum = 0;
        
        sum  = (min(luckNumber[lSize][1],(ll)r)-l+1)*luckNumber[lSize][1];
        for(int i=lSize+1;i<rSize;i++) sum+=luckSum[i];
        if(lSize!=rSize){
            sum += (r-luckNumber[rSize][0]+1)*luckNumber[rSize][1];
        }
        
        printf("%I64d
    ",sum);
        
        return 0;
    } 

    由cnt可以知道每次循环至多需要2^9次, 而至多只有5层循环 ,O(5*2^9);

  • 相关阅读:
    Android开发学习笔记-关于Android的消息推送以及前后台切换
    C#文件操作工具类
    c#取得应用程序根目录
    Visual Studio 2012中使用GitHub
    C#邮件发送
    jquery判断某个属性是否存在 hasAttr
    js 如何让两个等长的数组产生键值对关系
    js判断一个元素是否在数组中
    日期控件
    react 生命周期函数的一些心得体会
  • 原文地址:https://www.cnblogs.com/yuanshixingdan/p/5481508.html
Copyright © 2011-2022 走看看