Jingdong 2018 Autumn Recruitment Programming Questions

C++ development engineer Jingdong 2018 autumn recruitment programming questions (code follow-up update...)


1. Magic number

Divide the digits of a number n into two parts, and the sum of the two parts is equal, then the number is called a magic number. For example, 242 is divided into [2,2], [4]. Input a range [l, r], output the number of magic numbers in this range.

Example:

Input: 1,
50
Output:
4

Parse:

To determine whether a number is a magic number, you should first obtain its various digits {a1, a2, a3, a4, ...}. According to the definition of a magic number, the digits need to be divided into two parts, and the sum of the elements of the two parts is equal, so the sum of all digits and sum{a1, a2, a3, a4, …} must be even. If it is not even, it must not be a magic number .

Therefore, the problem evolves to find a subset in {a1, a2, a3, a4, …} such that sum{subset} = sum/2 .

Obviously, this is a 0-1 knapsack problem . Backtracking and dynamic programming can be used .
Dynamic programming is used here, and dp[i][j] is used to indicate whether the sum of the elements of the subarray {a1, a2, a3, a4,..., ai} is equal to j .
Initial dp[i][0] = true (all elements are not selected, sum is j)
if the i-th element is not selected, then dp[i][j] = dp[i-1][j]
If the i-th element is selected i elements, then dp[i][j] = dp[i-1][j-num[i]]
Therefore, dp[i][j] = dp[i-1][j] || dp[ i-1][j-num[i]] .
dp[n][newSum] means whether a subset can be found whose element sum is sum/2.

C++ code implementation

#include <iostream>
#include <vector>
using namespace std;
int l=0,r=0;

//动态规划
bool canPartition(vector<int>&dicts,int n,int sum)
{
    vector<vector<bool>> dp(n+1,vector<bool>(sum+1,false));
    for(int i=0; i<=n; i++)
        dp[i][0] = true;
    for(int j=1; j<=sum; j++){
        for(int i=1; i<=n; i++){
            dp[i][j] = dp[i-1][j]; //不选第i个元素
            if(j>=dicts[i-1])      //选第i个元素
                dp[i][j] = dp[i][j] || dp[i-1][j-dicts[i-1]];
        }
    }
    return dp[n][sum];
}

bool isSqs(int num)
{
    vector<int> dicts(10,0);
    int k=0,sum=0;
    while(num!=0){
        dicts[k++] = num%10;
        num /= 10;
        sum += dicts[k-1];
    }
    if(sum & 1)
        return false;
    return canPartition(dicts,k,sum>>1);
}

int sqs()
{
    if(r<11)
        return 0;
    if(r==11)
        return 1;
    int cnt = 1;
    for(int i=12; i<=r; i++){
        if(isSqs(i))
            cnt++;
    }
    return cnt;
}

int main()
{
    cin>>l>>r;
    cout<<sqs();
    return 0;
}

2. Crazy Sequence

There is an infinite sequence, {1, 2, 2, 3, 3, 3, 4, 4, 4, 4, ...}, and the number n appears n times in the sequence and is continuous. Input an integer n, output the nth number. The range of n is [1,10^18].

Example:

Input:
169
Output:
18

Parse:

Use dp[i] to represent the index of the number i in the infinite sequence, then:
dp[1] = 1
dp[2] = 3
dp[3] = 6
dp[4] = 10
dp[5] = 15

dp[ n] = n*(n+1)/2
Therefore, to judge the number of the nth item, you should find dp[i]<= n <=dp[i+1],
where i or i+1 is the result.

C++ code implementation
The following code will time out.

int getIndex(long long& n)
{
    if(n==1)
        return 1;
    long long sum = 0,last = 1;
    for(int i=sqrt(n); i<n && sum<=n; i++){
        sum = ((i+1)*i)>>1;
        if(sum==n)
            return i;
        else if(sum < n)
            last = i;
    }
    return last+1;
}

int main()
{
    long long n;
    cin>>n;
    cout<<getIndex(n);
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326284998&siteId=291194637