1. 程式人生 > >牛客網 牛客練習賽13

牛客網 牛客練習賽13

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 262144K,其他語言524288K
64bit IO Format: %lld

題目描述

定義一個數字為幸運數字當且僅當它的所有數位都是4或者7。
比如說,47、744、4都是幸運數字而5、17、467都不是。
定義next(x)為大於等於x的第一個幸運數字。給定l,r,請求出next(l) + next(l + 1) + ... + next(r - 1) + next(r)。

輸入描述:

兩個整數l和r (1 <= l <= r <= 1000,000,000)。

輸出描述:

一個數字表示答案。

示例1

輸入

2 7

輸出

33

示例2

輸入

7 7

輸出

7

分析:

比賽的時候,採取的方式是進位的情況,就是從 l 遍歷到 r ,對於每一個數,我採取的方式是從末尾開始判斷,如果是小於等於 4 ,則將該數變為 4 ,如果是大於 4 且小於後等於 7 ,則將該數變為 7 ,但如果是大於 7 的話,則將該數變為 4,並且向前進一位,感覺方法很好,但是提交就是執行超時。。。。。。

說一個簡單快捷的方法吧,我們可以以二叉樹的形式將所有在範圍內的幸運數字存在數組裡,因為題中的資料是1000 000 000,所以最大的幸運數就是 4444 444 444,可知該樹的深度為11,因為第一層我們設成 0,而陣列是從下標為 0 開始的,所以我們實際上就是去掉一個 0 ,多加一個最大幸運數,所以節點個數相當於深度為 10 的節點個數。當將幸運數從小到大的打表出來之後,就可以遍歷選取 l 到 r 的幸運數即可,注意資料得用 long long int 。

#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<math.h>
using namespace std;

long long int s[1030];

int main()
{
    long long int l,r,sum=0,bj=0,n;
    for(int i=1;i<=1024;i++)///打表將幸運數存入s陣列
    {
        int a=i/2+1;
        if(i%2==1)
            n=4;
        else
            n=7;
        s[i]=s[i-a]*10+n;
    }
    scanf("%lld %lld",&l,&r);
    for(int i=1;i<=1024;i++)
    {
        if(s[i]>=l)
        {
            for(;l<=s[i];l++)
            {
                sum+=s[i];
                if(l==r)
                {
                    bj=1;
                    break;
                }
            }
        }
        if(bj)
            break;
    }
    printf("%lld\n",sum);
    return 0;
}