ZOJ 1095. Humble Numbers

来源:https://www.cnblogs.com/hoodlum1980/archive/2019/09/27/11595451.html
-Advertisement-
Play Games

如果一個數的所有質數因數都來自於 { 2, 3, 5, 7 } 這個集合,就把這個數字叫做“謙虛數”(Humber Number),現在給出一個數字 i (1 <= i <= 5842),要求輸出第 i 個 humber number。 ...


  題目鏈接:《Humble Numbers》

  題意:如果一個數的所有質數因數都來自於 { 2, 3, 5, 7 } 這個集合,就把這個數字叫做“謙虛數”(Humber Number),現在給出一個數字 i (1 <= i <= 5842),要求輸出第 i 個 humber number。比如說,前 20 個 humber number 是:1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 27。

 

  分析:這個題目的描述是非常簡單的。從 i 的限定範圍最大是 5842 以及範例輸出來看,很顯然出題人暗示了我們這個題目中涉及到的 humber number 不會超出 int 的範圍。因此我們可以放心的使用 int,而不用擔心超出表示範圍。

  其次可以很容易的想到,需要一個 int 數組,把需要的所有 humber number 放進去作為供查詢的表。但是生成這個表會比較耗時,所以很容易超過 2 秒的運行時間限制。所以我們需要更快的建立這個數組,則觀察這個序列,因為所有的數字都是如下形式:

  x [ i ] = ( 2 ^ k [0] ) * ( 3 ^ k [1] ) * ( 5 ^ k [2] ) * ( 7 ^ k [3] ) ;

  這裡 k 是一個數組,裡面的元素表示 2, 3, 5, 7 這四個因數的冪,因此考慮從 x [ i ] 跳到下一個 x [ i + 1] 時,就是數字的這 4 個因數的冪在發生變化。因此只要知道從 x[ i ] 變化到 x[ i + 1] 時,數組 k 如何變化即可。因此我們需要找出前 5842 個 humber number 中的所有規則,這樣就可以快速的得到前 5842 個 humber number,組建成我們要查的表。

  觀察前面幾個數字,很容易發現出這些規則,例如:

  1->2, 2->3, 3->4, 4->5, 5->6, ...

  從 10 到 12 本質上還是應用的 5->6 。因此只有相鄰且互質的數字(a, b),才屬於我們要找的規則(a -> b),其他的相鄰數字都是應用了上述規則中的某一條。

  同時這些規則還有優先順序的順序之分,從錶面上看,應該是數字 a 和 b 越大,規則越優先。但實際上並非如此,例如:

  從 75 到 80 ,應用的實際規則是 15->16 ,而不是 25->27 (這會產生從 75 變成 81,跳過了 80)。因此規則的優先順序排序需要按照 a->b 的放大倍數進行從小到大排序。放大倍數(b / a)越小的規則,越優先。考慮到這個規則很多(實際有 76 條),而且涉及的數字很大,所以人工找出所有規則是不現實的。所以我使用一個程式(稱之為代碼生成器)來專門找出手游規則,並將其輸出成一個函數的代碼,函數的名稱是 GetNext,含義是根據當前的 humber number ,找出下一個 humber number。如下:

#include <vector>
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <string.h>

typedef struct tagNODE
{
    int from;
    int to;
    double ratio; //= to / from;
} NODE;

//x1, x2 是否是已經排好序的。
bool IsSuccessive(NODE x1, NODE x2)
{
    return x1.ratio < x2.ratio;
}

void Init(std::vector<int> &v1, int nSize)
{
    v1.reserve(nSize);
    v1.clear();
    v1.push_back(1);
    int nNumber = 2;
    int tmp;
    while(v1.size() < nSize)
    {
        tmp = nNumber;
        while((tmp % 2) == 0) tmp /= 2;
        while((tmp % 3) == 0) tmp /= 3;
        while((tmp % 5) == 0) tmp /= 5;
        while((tmp % 7) == 0) tmp /= 7;
        if(tmp == 1)
            v1.push_back(nNumber);
        ++nNumber;
    }
}

//x1, x2 是否是互質的(沒有公共因數)
bool no_comm_factor(int x1, int x2)
{
    if(x1 % 2 == 0 && x2 % 2 == 0)
        return false;
    if(x1 % 3 == 0 && x2 % 3 == 0)
        return false;
    if(x1 % 5 == 0 && x2 % 5 == 0)
        return false;
    if(x1 % 7 == 0 && x2 % 7 == 0)
        return false;
    return true;
}

//give x, find k;
//x = 2^k[0] * 3^k[1] * 5^k[2] * 7^k[3];
void GetK(int x, int k[4])
{
    memset(k, 0, sizeof(int) * 4);
    while((x & 1) == 0) 
    {
        x /= 2;
        k[0]++;          
    }
    while(x % 3 == 0)
    {
        x /= 3;
        k[1]++;
    }
    while(x % 5 == 0)
    {
        x /= 5;
        k[2]++;
    }
    while(x % 7 == 0)
    {
        x /= 7;
        k[3]++;
    }
}

int main(int argc, char* argv[])
{
    std::vector<int> v1;
    //計算出前 5842 個 humber number,這一步需要花比較長的時間。
    Init(v1, 5842);

    //找出所有策略(即找出所有的相鄰的互質的 humber number 對)。
    std::vector<NODE> nodes;
    for(int i = 5841; i > 0; --i)
    {
        if(no_comm_factor(v1[i - 1], v1[i]))
        {
            NODE item;
            item.from = v1[i - 1];
            item.to = v1[i];
            item.ratio = item.to * 1.0 / item.from;
            nodes.push_back(item);
        }
    }

    //按照放大倍數從小到大進行規則排序。
    std::sort(nodes.begin(), nodes.end(), IsSuccessive);

    int iRule = 0;
    int k1[4], k2[4];
    char buf[1024], *pos;
    FILE *fp = fopen("GetNextK_code.cpp", "w");
    fputs("void GetNext(int* k)\n{\n", fp);
    typename std::vector<NODE>::const_iterator it;
    for(it = nodes.begin(); it != nodes.end(); ++it)
    {
        ++iRule;

        GetK(it->from, k1);
        GetK(it->to,   k2);

        if(iRule == 1) strcpy(buf, "\tif(");
        else if(iRule == nodes.size()) strcpy(buf, "else");
        else strcpy(buf, "\telse if(");
        pos = buf + strlen(buf);

        if(k1[0]) 
        {
            sprintf(pos, "k[0] >= %d && ", k1[0]);
            pos += strlen(pos);
        }
        if(k1[1])
        {    
            sprintf(pos, "k[1] >= %d && ", k1[1]);
            pos += strlen(pos);
        }
        if(k1[2])
        {
            sprintf(pos, "k[2] >= %d && ", k1[2]);
            pos += strlen(pos);
        }
        if(k1[3])
        {
            sprintf(pos, "k[3] >= %d && ", k1[3]);
            pos += strlen(pos);
        }

        if(iRule == nodes.size())
        {
            //最後一條規則
            sprintf(pos,  " //(rule %d) %d -> %d (%lf);\n\t{\n", 
                iRule, it->from, it->to, it->ratio);
        }
        else
        {
            pos -= 4; //remove " && ";
            sprintf(pos, ") //(rule %d) %d -> %d (%lf);\n\t{\n", 
                iRule, it->from, it->to, it->ratio);
        }
        pos += strlen(pos);

        //From
        if(k1[0])
        {
            sprintf(pos, "\t\tk[0] -= %d;\n", k1[0]);
            pos += strlen(pos);
        }
        if(k1[1])
        {
            sprintf(pos, "\t\tk[1] -= %d;\n", k1[1]);
            pos += strlen(pos);
        }
        if(k1[2])
        {
            sprintf(pos, "\t\tk[2] -= %d;\n", k1[2]);
            pos += strlen(pos);
        }
        if(k1[3])
        {
            sprintf(pos, "\t\tk[3] -= %d;\n", k1[3]);
            pos += strlen(pos);
        }

        //To
        if(k2[0])
        {
            sprintf(pos, "\t\tk[0] += %d;\n", k2[0]);
            pos += strlen(pos);
        }
        if(k2[1])
        {
            sprintf(pos, "\t\tk[1] += %d;\n", k2[1]);
            pos += strlen(pos);
        }
        if(k2[2])
        {
            sprintf(pos, "\t\tk[2] += %d;\n", k2[2]);
            pos += strlen(pos);
        }
        if(k2[3])
        {
            sprintf(pos, "\t\tk[3] += %d;\n", k2[3]);
            pos += strlen(pos);
        }
        strcpy(pos, "\t}\n");
        fputs(buf, fp);
        fflush(fp);
    }
    fputs("}\n", fp);
    fclose(fp);
    return 0;
}
Code_Generator

  使用上面的代碼生成器,我們就得到了所有的規則,就可以方便的真正的寫用於提交的代碼了。

  為了從數組 k 計算 humber number 的方便,這裡我把 2, 3, 5, 7 的 n 次方提前計算好放到一個數組裡,這樣就能更快速的計算出 humber number。這樣這個題目也就算基本完成了。但是這也只不過是完成了這個題目的一半而已,因此這個題目還有一半大坑在於輸出格式中的 th 尾碼!為此我 WA 了 2, 3 次以後才把規則寫對。簡單來說這裡需要特別註意的就是:

  所有形如 xx11, xx12, xx13 尾碼都是 th (而不僅僅是 11, 12, 13 ),除此以為的 xxx1 用 st,xxx2 用 nd,xxx3 用 rd,所有其他都用 th。例如,1011th, 1012th ,1023th,這裡需要特別註意。

  最終提交代碼如下:

// ZOJ1095_HumbleNumbers.cpp
//

#include <vector>
#include <iostream>

//選擇出下一組 k 值,按照如下規則。
// x = (2^k[0]) * (3^k[1]) * (5^k[2]) * (7^k[3]);
void GetNext(int* k);

int main(int argc, char* argv[])
{
    int i, x;
    int k[4] = { 0, 0, 0, 0 };
    int a2[31] = { 1 }; //a2[k] = 2^k;
    int a3[20] = { 1 }; //a3[k] = 3^k;
    int a5[14] = { 1 }; //a5[k] = 5^k;
    int a7[12] = { 1 }; //a7[k] = 7^k;
    for(i = 1; i < 31; i++)
    {
        a2[i] = a2[i - 1] * 2;
        if(i < 20) a3[i] = a3[i - 1] * 3;
        if(i < 14) a5[i] = a5[i - 1] * 5;
        if(i < 12) a7[i] = a7[i - 1] * 7;
    }
    std::vector<int> v1;
    v1.reserve(5842);
    v1.push_back(1);
    while(v1.size() < 5842)
    {
        GetNext(k);
        x = a2[k[0]] * a3[k[1]] * a5[k[2]] * a7[k[3]];
        v1.push_back(x);
    }
    while(true)
    {
        std::cin >> i;
        if(i == 0) break;
        else if(i % 100 != 11 && i % 10 == 1)
            std::cout << "The " << i << "st humble number is " << v1[i - 1] << "." << std::endl;

        else if(i % 100 != 12 && i % 10 == 2)
            std::cout << "The " << i << "nd humble number is " << v1[i - 1] << "." << std::endl;
        
        else if(i % 100 != 13 && i % 10 == 3)
            std::cout << "The " << i << "rd humble number is " << v1[i - 1] << "." << std::endl;
        
        else
            std::cout << "The " << i << "th humble number is " << v1[i - 1] << "." << std::endl;
    }
    return 0;
}

//以下代碼是從另一個程式生成的。
//根據當前的 humble number,選出下一個 humble number。
void GetNext(int* k)
{
    if(k[1] >= 13 && k[3] >= 2) //(rule 1) 78121827 -> 78125000 (1.000041);
    {
        k[1] -= 13;
        k[3] -= 2;
        k[0] += 3;
        k[2] += 10;
    }
    else if(k[0] >= 4 && k[3] >= 9) //(rule 2) 645657712 -> 645700815 (1.000067);
    {
        k[0] -= 4;
        k[3] -= 9;
        k[1] += 17;
        k[2] += 1;
    }
    else if(k[0] >= 4 && k[2] >= 6) //(rule 3) 250000 -> 250047 (1.000188);
    {
        k[0] -= 4;
        k[2] -= 6;
        k[1] += 6;
        k[3] += 3;
    }
    else if(k[0] >= 1 && k[1] >= 7) //(rule 4) 4374 -> 4375 (1.000229);
    {
        k[0] -= 1;
        k[1] -= 7;
        k[2] += 4;
        k[3] += 1;
    }
    else if(k[0] >= 5 && k[3] >= 8) //(rule 5) 184473632 -> 184528125 (1.000295);
    {
        k[0] -= 5;
        k[3] -= 8;
        k[1] += 10;
        k[2] += 5;
    }
    else if(k[0] >= 5 && k[1] >= 1 && k[2] >= 2) //(rule 6) 2400 -> 2401 (1.000417);
    {
        k[0] -= 5;
        k[1] -= 1;
        k[2] -= 2;
        k[3] += 4;
    }
    else if(k[0] >= 9 && k[2] >= 1 && k[3] >= 5) //(rule 7) 43025920 -> 43046721 (1.000483);
    {
        k[0] -= 9;
        k[2] -= 1;
        k[3] -= 5;
        k[1] += 16;
    }
    else if(k[0] >= 6 && k[3] >= 7) //(rule 8) 52706752 -> 52734375 (1.000524);
    {
        k[0] -= 6;
        k[3] -= 7;
        k[1] += 3;
        k[2] += 9;
    }
    else if(k[0] >= 10 && k[3] >= 4) //(rule 9) 2458624 -> 2460375 (1.000712);
    {
        k[0] -= 10;
        k[3] -= 4;
        k[1] += 9;
        k[2] += 3;
    }
    else if(k[0] >= 7 && k[1] >= 4 && k[3] >= 6) //(rule 10) 1219784832 -> 1220703125 (1.000753);
    {
        k[0] -= 7;
        k[1] -= 4;
        k[3] -= 6;
        k[2] += 13;
    }
    else if(k[0] >= 14 && k[2] >= 3 && k[3] >= 1) //(rule 11) 14336000 -> 14348907 (1.000900);
    {
        k[0] -= 14;
        k[2] -= 3;
        k[3] -= 1;
        k[1] += 15;
    }
    else if(k[0] >= 11 && k[3] >= 3) //(rule 12) 702464 -> 703125 (1.000941);
    {
        k[0] -= 11;
        k[3] -= 3;
        k[1] += 2;
        k[2] += 7;
    }
    else if(k[0] >= 15) //(rule 13) 32768 -> 32805 (1.001129);
    {
        k[0] -= 15;
        k[1] += 8;
        k[2] += 1;
    }
    else if(k[0] >= 12 && k[1] >= 5 && k[3] >= 2) //(rule 14) 48771072 -> 48828125 (1.001170);
    {
        k[0] -= 12;
        k[1] -= 5;
        k[3] -= 2;
        k[2] += 11;
    }
    else if(k[2] >= 8 && k[3] >= 3) //(rule 15) 133984375 -> 134217728 (1.001742);
    {
        k[2] -= 8;
        k[3] -= 3;
        k[0] += 27;
    }
    else if(k[1] >= 7 && k[2] >= 4 && k[3] >= 2) //(rule 16) 66976875 -> 67108864 (1.001971);
    {
        k[1] -= 7;
        k[2] -= 4;
        k[3] -= 2;
        k[0] += 26;
    }
    else if(k[1] >= 1 && k[2] >= 10) //(rule 17) 29296875 -> 29360128 (1.002159);
    {
        k[1] -= 1;
        k[2] -= 10;
        k[0] += 22;
        k[3] += 1;
    }
    else if(k[1] >= 14 && k[3] >= 1) //(rule 18) 33480783 -> 33554432 (1.002200);
    {
        k[1] -= 14;
        k[3] -= 1;
        k[0] += 25;
    }
    else if(k[3] >= 10) //(rule 19) 282475249 -> 283115520 (1.002267);
    {
        k[3] -= 10;
        k[0] += 21;
        k[1] += 3;
        k[2] += 1;
    }
    else if(k[1] >= 8 && k[2] >= 6) //(rule 20) 102515625 -> 102760448 (1.002388);
    {
        k[1] -= 8;
        k[2] -= 6;
        k[0] += 21;
        k[3] += 2;
    }
    else if(k[1] >= 15 && k[2] >= 2) //(rule 21) 358722675 -> 359661568 (1.002617);
    {
        k[1] -= 15;
        k[2] -= 2;
        k[0] += 20;
        k[3] += 3;
    }
    else if(k[2] >= 1 && k[3] >= 6) //(rule 22) 588245 -> 589824 (1.002684);
    {
        k[2] -= 1;
        k[3] -= 6;
        k[0] += 16;
        k[1] += 2;
    }
    else if(k[2] >= 7 && k[3] >= 3) //(rule 23) 26796875 -> 26873856 (1.002873);
    {
        k[2] -= 7;
        k[3] -= 3;
        k[0] += 12;
        k[1] += 8;
    }
    else if(k[1] >= 5 && k[3] >= 5) //(rule 24) 4084101 -> 4096000 (1.002913);
    {
        k[1] -= 5;
        k[3] -= 5;
        k[0] += 15;
        k[2] += 3;
    }
    else if(k[2] >= 13) //(rule 25) 1220703125 -> 1224440064 (1.003061);
    {
        k[2] -= 13;
        k[0] += 8;
        k[1] += 14;
    }
    else if(k[2] >= 3 && k[3] >= 2) //(rule 26) 6125 -> 6144 (1.003102);
    {
        k[2] -= 3;
        k[3] -= 2;
        k[0] += 11;
        k[1] += 1;
    }
    else if(k[1] >= 12 && k[3] >= 4) //(rule 27) 1275989841 -> 1280000000 (1.003143);
    {
        k[1] -= 12;
        k[3] -= 4;
        k[0] += 14;
        k[2] += 7;
    }
    else if(k[2] >= 9) //(rule 28) 1953125 -> 1959552 (1.003291);
    {
        k[2] -= 9;
        k[0] += 7;
        k[1] += 7;
        k[3] += 1;
    }
    else if(k[1] >= 6 && k[3] >= 1) //(rule 29) 5103 -> 5120 (1.003331);
    {
        k[1] -= 6;
        k[3] -= 1;
        k[0] += 10;
        k[2] += 1;
    }
    else if(k[2] >= 5) //(rule 30) 3125 -> 3136 (1.003520);
    {
        k[2] -= 5;
        k[0] += 6;
        k[3] += 2;
    }
    else if(k[1] >= 13) //(rule 31) 1594323 -> 1600000 (1.003561);
    {
        k[1] -= 13;
        k[0] += 9;
        k[2] += 5;
    }
    else if(k[3] >= 9) //(rule 32) 40353607 -> 40500000 (1.003628);
    {
        k[3] -= 9;
        k[0] += 5;
        k[1] += 4;
        k[2] += 6;
    }
    else if(k[1] >= 7 && k[2] >= 1) //(rule 33) 10935 -> 10976 (1.003749);
    {
        k[1] -= 7;
        k[2] -= 1;
        k[0] += 5;
        k[3] += 3;
    }
    else if(k[3] >= 6) //(rule 34) 117649 -> 118098 (1.003816);
    {
        k[3] -= 6;
        k[0] += 1;
        k[1] += 10;
    }
    else if(k[3] >= 5) //(rule 35) 16807 -> 16875 (1.004046);
    {
        k[3] -= 5;
        k[1] += 3;
        k[2] += 4;
    }
    else if(k[0] >= 4 && k[2] >= 2 && k[3] >= 2) //(rule 36) 19600 -> 19683 (1.004235);
    {
        k[0] -= 4;
        k[2] -= 2;
        

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • RESTful 是最流行的 API 設計規範,但是什麼是 RESTful?表現層狀態轉移,這恐怕誰都看不懂。本文用最通俗的說法,講明白什麼是 RESTful。 ...
  • 概述 簡單介紹一下七大設計原則: 1. 開閉原則 :是所有面向對象設計的核心,對擴展開放,對修改關閉 2. 依賴倒置原則 :針對介面編程,依賴於抽象而不依賴於具體 3. 單一職責原則 :一個介面只負責一件事情,只能有一個原因導致類變化 4. 介面隔離原則 :使用多個專門的介面,而不是使用一個總介面 ...
  • 建造者模式主要解決問題: 具備若幹成員,當其中一個成員發生變化,其它成員也隨著發生變化。 這種複雜對象的生成需要使用建造者模式來生成。 建造者設計模式的結構圖: 來源:http://c.biancheng.net/view/1354.html 例子: 街頭籃球角色創建模擬 街頭籃球: 中鋒、前鋒、後 ...
  • 一 QuerySet 可切片 使用Python 的切片語法來限制 記錄的數目 。它等同於SQL 的 和 子句。 不支持負的索引(例如 )。通常, 的切片返回一個新的 —— 它不會執行查詢。 可迭代 惰性查詢 是惰性執行的 —— 創建 不會帶來任何資料庫的訪問。你可以將過濾器保持一整天,直到 需要求值 ...
  • 程式結構設計理論(Android) 作者:鄧能財 2019年9月24日 個人簡介 姓名:鄧能財 年齡:26 畢業學校:東華理工大學 院系:理學院 專業:信息與計算科學 郵箱:[email protected] [明德厚學,愛國榮校] 本文的PPT版、以及作為案例的App項目可以從這裡下載: "程式結 ...
  • Java 鎖之樂觀鎖和悲觀鎖 [TOC] Java 按照鎖的實現分為樂觀鎖和悲觀鎖,樂觀鎖和悲觀鎖並不是一種真實存在的鎖,而是一種設計思想,樂觀鎖和悲觀鎖對於理解 Java 多線程和資料庫來說至關重要,那麼本篇文章就來詳細探討一下這兩種鎖的概念以及實現方式。 悲觀鎖 是一種悲觀思想,它總認為最壞的情 ...
  • " ⭐ 我的網站: www.mengyingjie.com ⭐ " 1要求 編寫程式檢查該字元串的括弧是否成對出現,而且不能交叉出現。 輸入: 一個字元串,裡邊可能包含“()”、"{}"、“[]”三種括弧,“ ”結束 輸出: 成功:代表括弧成對出現並且嵌套正確 失敗:未正確使用括弧字元。 2分析 用 ...
  • " ⭐ 我的網站: www.mengyingjie.com ⭐ " 嚴蔚敏數據結構源碼及習題解析 習題解析未更新完整,以後更新 內容已上傳到github,歡迎star和fork: "https://github.com/MengYingjie/YanWeimin DataStructure Sour ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...