簡體   English   中英

用於計算不包含給定數字的第n個數字的程序

[英]Program to compute n-th number that doesn't contain given digit

我被要求編寫一個C ++程序來計算包含給定數字的第n個數字, 並且執行時間低於0.1秒。 內存似乎不是問題,因為我允許使用高達64 MB的內存。

問題的原始文本是這樣的:

Cifra4

為了represent numbers ,決定不再使用數字C 因此,從自然數字數組中,將刪除包含數字C所有數字。 讓新數組為S.

要求

1)確定S中 N-th個數。

2) YZ所有自然數的數組中的兩個自然數 確定數量
自然數從YZ刪除。

輸入數據

輸入文件cifra4.in包含表示需求類型的第一個數字T 如果T == 1 ,則第二行將包含數字C和數字N 如果T == 2 ,則第二行將包含數字C和兩個自然數YZ

輸出數據

在輸出文件中, cifra4.out將在第一行中包含一個根據需求類型的自然數。

限制和澄清

 1 ≤ N ≤ 10 ^ 13 0 ≤ C ≤ 9 1 ≤ Y ≤ 10 ^ 13 1 ≤ Z ≤ 10 ^ 13 for 20% of the tests, N will have a maximum of 5 digits for 20% of the tests, Y and Z will have a maximum of 6 digits 

例1

cifra4.in

 1 0 11 

cifra4.out

 12 

例2

cifra4.in

 2 1 3 20 

cifra4.out

10

我最好的嘗試是確定(或至少應該)不包含數字“0”的第n個數字的代碼,但對於10 ^ 13它返回23210987654321 ,顯然包含0

我的速度較慢但正確的方法是我最終保留的。 這是代碼:

#include <fstream>

std::ifstream in("cifra4.in");
std::ofstream out("cifra4.out");

const long long pow_of_10[14] = {0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000,
                                 10000000000, 100000000000, 1000000000000};

void req_1 ()
{
    short digit;
    long long n;
    in >> digit >> n;
    for (long long i = 0; i <= n; i++)
    {
        long long nr = i;
        if (nr)
        {
            long k = 1;
            do
            {
                if (nr % 10 == digit)
                {
                    n += pow_of_10[k];
                    i += pow_of_10[k] - 1;
                    break;
                }
                nr /= 10;
                k++;
            }
            while (nr);
        }
        else if (digit == 0) n++;
    }
    out << n - 1;
}

void req_2()
{
    short digit;
    long long lhs, rhs;
    long long elim = 0;
    in >> digit >> lhs >> rhs;
    for (long long i = lhs; i <= rhs; i++)
    {
        long long nr = i;
        while (nr)
        {
            if (nr % 10 == digit)
            {
                elim++;
                break;
            }
            nr /= 10;
        }
    }
    out << elim;
}

int main()
{
    short requirement;
    in >> requirement;
    if (requirement == 1)
        req_1();
    else
        req_2();
}

注意

我不是要求代碼,但是對於想法,可能的算法可以在適當的時間執行高達10 ^ 13,最好是問題所要求的時間,但1秒對我來說沒問題。

想象一下, 9是禁止的數字。 在這種情況下,您只需將您的號碼轉換為基數為9即可。

現在,當禁止數字不同時會發生什么,比方說d 它仍然是一個基數為9的數字,但你必須映射你的數字,這樣d以下的數字不受影響, d和以上數字映射到數字d + 1

例如,當禁止數字為7n125

  • 步驟1:轉換為base-9:125 10 = 148 9
  • 第2步:映射數字。 1→1,4→4,8→9

解決方案是149。

由於數字的十進制數字彼此“獨立”,因此在該設置中,一個數字不會影響任何其他數字 - 一旦您修復了(至少一個)更高有效數字的前綴,則n'更少 - 有效數字,你知道你有完全(10 - 1)^ n'= 9 ^ n'數字與該前綴和未固定部分沒有禁止數字。 例如,對於以1開頭的3位數字,確切地說有81個數字,其中沒有0。

這里唯一的“阻礙”是將最高有效數字設置為零意味着您為不同的數字位數(012,0012等)獲得相同的數字。 但是你也應該能夠解決這個問題 - 通過確定第n個數字需要多少位數而沒有你的禁號。 與我上面描述的論點非常相似。 如果您的禁止數字為0或10-2 = 8,那么您知道您有10-1 = 9個選項。

暫無
暫無

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

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