簡體   English   中英

K 步中可能的最大 n 位數

[英]the maximum n digit number possible in K steps

有人可以幫我解決這個問題嗎?

聲明: - 從 0 開始的最大可能的 n 位數字是多少,我們可以在 K 步中僅使用 2 次操作:- 乘以 3 或遞增 2。

示例:N =2 K = 5; -> (0->2->6->8->24->72) 72 是答案

N = 2,K = 51 -> (0->2->6->8->10->30->32->96->98)。 98 是我們可以得到的最大值,所以需要檢查 rest 的動作。

我的 2 狀態遞歸解決方案:-

public static void largestNDigitNumber(long[] highest, long maxValue, long k, long currentValue) {
    if (highest[0] == (maxValue - 2)) return; //no need to do anything as we get 98 as highest.
    if (k < 0) return; //checking for steps

    if (highest[0] < currentValue && currentValue <= (maxValue - 2)) {
        highest[0] = currentValue;
    }

    largestNDigitNumber(highest, maxValue, (k - 1), (currentValue * 3));
    largestNDigitNumber(highest, maxValue, (k - 1), (currentValue + 2));
}


public static void main(String[] args) {
    int n = 2;
    long k = 51;
    long maxValue = (long) Math.pow(10, n);
    long[] highest = new long[1];
    largestNDigitNumber(highest, maxValue, (k - 1), 2);
    if (highest[0] < (long) Math.pow(10, (n - 1))) {
        System.out.println("-1"); // if it is not possible to make n digit in given steps
    } else System.out.println(highest[0]);
}

當“k”較小時,它給出了正確的答案,但對於較大的“k”值,它不顯示任何輸入。 對於 n=2 和 k = 51,它不顯示任何內容。

請幫我改進這段代碼

該問題相當於詢問小於 10^n/2 且數字和加上長度小於或等於 k+1 的最大基數為 3 的數是什么。 (答案是基數 3 的兩倍)。

例如,N=2 K=5。 小於 50 且長度加位數之和小於等於 6 的最大基數為 3 的數是多少。答案:1100(十進制 36),所以原題的答案是 36*2=72。

對於 N=2,K=51,小於 50 的最大基數為 3 的數字是 2001(十進制 49)並且長度總和加上數字總和 = 7,遠小於 K+1。

鑒於這種表示,很容易在 O(n) 時間內解決問題(實際上,您可以使用鉛筆和紙來解決它)。 base-3 數的長度 d 盡可能大,使得 3^d < 10^n/2 並且 d<=K。 然后從最重要的開始貪婪地填寫數字的數字,直到你有數字總和 K+1-d (或者你的數字用完了)。

等價

舉個例子來說明這兩個問題的等價性:如果你有一個以 3 為底的加倍數字,比如 2 * 2101,那么這相當於2 * (1+3*3*(1+3*(1+1)))) = (2 + 3*3*(2+3*(2+2))) 相反,連續添加超過 2 個 2 是沒有意義的,因為 (2+2+2)=3*2 (因此您可以節省操作)。 運算的數量等於以 3 為底的數字的數量(因為每個數字對應於乘以 3)加上數字總和(因為使 1 需要 1 的一個加法,而 2 需要 1 的兩次加法)。

我嘗試過這樣的事情。 它似乎工作正常。

getMaxNumber(2, 5)  ==> 72
getMaxNumber(2, 51) ==> 98


private int getMaxNumber(int n, int k){
    int N = 0;
    for (int i = 0; i < n; i++) {
        N = N * 10 + 9;
    }
    int[] result = new int[1];
    helper(N, k, 0, 0, result);
    return result[0];
}


private void helper(int N, int K, int n, int k, int[] result){
    if(n > N) return;
    if(k <= K){
        result[0] = Math.max(result[0], n);
    }
    if(n > 0)
        helper(N, K, n * 3, k + 1, result);
    helper(N, K, n + 2, k + 1, result);
}

保持原始遞歸方法的風格。 我對其進行了一些修改以產生一個可行的解決方案:

public static long largestNDigitNumber(int n, long currentK, long maxK, long currentValue) {
    if (currentK > maxK || n < 1 || maxK < 1) return 0;
    if (currentValue >= Math.pow(10, n))
        return 0;
    
    long c1 = largestNDigitNumber(n, currentK + 1, maxK, currentValue * 3);
    long c2 = largestNDigitNumber(n, currentK + 1, maxK, currentValue + 2);

    if (c1 == 0 && c2 == 0)
        return currentValue;
    return c1 > c2 ? c1 : c2;
}


public static void main(String[] args) {
    int n = 2;
    long k = 51;
    long largest = largestNDigitNumber(n, 0, k, 0);
    System.out.println(largest); //98
}

此遞歸方法在此處返回值,而不是使用數組。 因此,在返回之前檢查一個返回值是否大於另一個或者它們都為 0。

+2 和 *3 操作都保持奇偶校驗,所以從 0 開始我們只能達到偶數。 我們可以從最大的偶數開始搜索:8、98、998、9998 等,看看到 0 的最短距離是多少。

如果我們正在尋找最短的距離,那么可以做出的選擇就更少了。 如果當前數字是 3 的倍數,則有兩種選擇,要么除以 3,要么減 2。否則,唯一的選擇是減 2。我懷疑在大多數情況下,除以 3 是更好的選擇,所以這可能是第一個嘗試讓樹更小的人。

如果最小步數小於 K,則可以根據需要使用盡可能多的除以 3 操作來生成正確的 K

如果最小步數等於K,那么問題就解決了。

如果最小步數大於 K,那么您需要選擇一個較低的起始數字。 作為初始計算的一部分,一些偶數已經包含在內。 您可以“免費”獲得這些,只要您包含少量記錄。 您只需要檢查由於“除以 3”步驟而錯過的大偶數。

我有 Javascript 解決方案供您試用。

function solution(N, K) {
    // write your code in JavaScript (Node.js 8.9.4)
// Getting the string as a parameter
// and typecasting it into an integer
let myFunc = num => Number(num); 
var intArr = Array.from(String(N), myFunc);
   for (var i = 0; i < intArr.length; i++) {
            var diff = Math.min('9' - intArr[i], K);
            intArr[i] += diff;
            K -= diff;
     }
        return parseInt(intArr.join(''));
}
console.log(solution(512,10))

作者:Hussaini Bulama ----軟件工程師 andela

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM