簡體   English   中英

C++ 數論:計算 max(y = a_i * x+ b_i) <= k 的最快方法

[英]C++ Number theory: Fastest way to compute max(y = a_i * x+ b_i) <= k

以下問題,當必須編寫快速代碼時:我有一個包含 2 個整數 a_i 和 b_i 的列表,我必須計算方程:y = (a_i * x + b_i),其中我只對 y 感興趣,而不對X。 所有 a_i 都是素數且彼此不同。 a_i = y / x,b_i = y % x。

y 有多種解,即使所有 a_i, b_i 對的 y 必須相同,因為 x 可以是任何整數。 因此我們有一個上限 k 並且 y <= k。 我想要盡可能高的 y(如果有解決方案)。 最大值(y)。

簡而言之:我想知道最大的整數 y(如果存在),y <= k 和給出的方程。 x >= 1。

我已經有一個理論上有效的“解決方案”,但這太慢了:

struct part {
unsigned int size, rest;
};

int solve(vector<part> &partions, int minK, int stepSize, int k) {
    int sol = 0;

    for (int i = k; i >= minK; i -= stepSize) {
        bool works = true;
        for (int j = 0; j < static_cast<int>(partions.size()); j++) {
            if ((i - partions[j].rest) % partions[j].size != 0) {
                works = false;
                break;
            }
        }
        if (works) return i;
    }



    return -1;
}

解釋:minK 是 max(a_i + b_i),因為我認為 y = a_i *1 + b_i 是一個方程的最小可能解,並且由於所有方程的 y 都相同,所以最大值是最好的下界。

stepSize 不是 1(為了使程序更快),而是 max(a_i),正如我所想的那樣,因為 max(a_i) 必須適合 y 並且 y = a_i * x + b_i,因此 x 是整數值,stepSize 是 a_i,而 max(a_i) 是最好的,因為這會減少循環運行的次數。

我現在使用 stepSize 嘗試從 k 到 minK 的所有 y,並測試所有對 a_i 和 b_i,如果它們滿足等式。 如果其中一個失敗,我必須繼續下去,直到找到解決方案或沒有解決方案 (-1)。

不幸的是,該算法太慢了(因為 a_i 和 b_i 可以達到 10^12),我想不出更多的優化。 我已經在互聯網上搜索了數論和算術,但找不到任何類似的東西。

你能幫我加快這段代碼的速度,或者提示我去一些處理這個問題的網站嗎?

您可以一次滿足一個 i,同時保留所有已經滿足的:step 是所有已經滿足的 a[i] 的 LCM(最初為 1)。 y 是滿足你已經做的所有那些的最小值。 關鍵概念是,滿足所有 i 的任何 Y 必須滿足您已經完成的所有Y=y+n*step ,因此它必須是Y=y+n*step 因此,對於每個 i,您可以直接計算y+n*step mod a[i] 等於 b[i] 的最小 n(如果有)並設置y=y+n*step和 step=lcm(step,a[一世])。 如果沒有這樣的 n 或者如果新的 y 大於 k,則中止。 一旦你完成了所有的 i,你就有了最小的 y,但你想要最大的 y 小於 k,這是一個微不足道的最終調整,因為它們相差很多步。

基礎數學 c++ 代碼左移或右移相同 if 條件 (k*x <b*k); k="1" or -1< div><div id="text_translate"><p> 下面是一個簡單的程序。</p><pre> int main() { int x, b = 3; //size_t x; size_t b = 3; char const *c = "moving_left"; // "moving_right" int k, border; if (,strcmp(c;"moving_left")) { k = 1; // moving left border = 0; x = 5; } else { k=-1; // moving right border = 7; x = 1; } while(true) { if (k*x&lt;b*k) { cerr&lt;&lt;c&lt;&lt;x&lt;&lt;'\n'; if (x==border){break;} } x-=k; } return 0; }</pre><p> 當我向左移動時,即 x 正在減少,我想在 x 落后於 b (x&lt;b) 之后打印“moving_left”。</p><p> 而當向右移動時,即 x 增加,我想在 x 穿過 b (x&gt;b) 后打印“moving_right”。</p><p> 當 x 和 b 是有符號整數時,上述程序可以正常工作,但是當我將它們聲明為無符號整數 (size_t) 時,由於 int 提升(當 k = -1 時)可能會失敗。</p><p> 我想在一個 while 循環中為 unsigned x &amp; b 運行上面的代碼(我喜歡將它們聲明為 unsigned,因為它們是未提及數組的索引)。 此外,在 if 條件 (k <em>x&lt;b</em> k) 中,我想要左比符號 (&lt;)。</p><p> 乘以負一僅適用於有符號整數。 是否有任何數學技巧可以使上述代碼適用於具有上述條件的無符號整數?</p></div></b*k);>

[英]basic mathematics c++ code for moving left or moving right for same if condition (k*x<b*k); k =1 or -1

暫無
暫無

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

相關問題 C++中x+=x和x=x+y有什么區別 C++:對於兩個帶有 do-while 循環的不同函數,為什么 x+=y 在一個 function 中給出與 x=x+y 相同的結果,而在另一個中卻不是? 在c ++中存儲節點(i).x和node(i).y數組值的最佳方法是什么? 用C ++查找數字除數的最快方法 Compute Power(x,y) 代碼說明 C++ 如何計算一個 4x4 矩陣橋(即 A * C = B,找到 C) 對於0 &lt;= x &lt;= 1和1的優化計算pow(x,y) 用x軸計算角度的最快方法 基礎數學 c++ 代碼左移或右移相同 if 條件 (k*x <b*k); k="1" or -1< div><div id="text_translate"><p> 下面是一個簡單的程序。</p><pre> int main() { int x, b = 3; //size_t x; size_t b = 3; char const *c = "moving_left"; // "moving_right" int k, border; if (,strcmp(c;"moving_left")) { k = 1; // moving left border = 0; x = 5; } else { k=-1; // moving right border = 7; x = 1; } while(true) { if (k*x&lt;b*k) { cerr&lt;&lt;c&lt;&lt;x&lt;&lt;'\n'; if (x==border){break;} } x-=k; } return 0; }</pre><p> 當我向左移動時,即 x 正在減少,我想在 x 落后於 b (x&lt;b) 之后打印“moving_left”。</p><p> 而當向右移動時,即 x 增加,我想在 x 穿過 b (x&gt;b) 后打印“moving_right”。</p><p> 當 x 和 b 是有符號整數時,上述程序可以正常工作,但是當我將它們聲明為無符號整數 (size_t) 時,由於 int 提升(當 k = -1 時)可能會失敗。</p><p> 我想在一個 while 循環中為 unsigned x &amp; b 運行上面的代碼(我喜歡將它們聲明為 unsigned,因為它們是未提及數組的索引)。 此外,在 if 條件 (k <em>x&lt;b</em> k) 中,我想要左比符號 (&lt;)。</p><p> 乘以負一僅適用於有符號整數。 是否有任何數學技巧可以使上述代碼適用於具有上述條件的無符號整數?</p></div></b*k);> 返回列表A和列表B中存在的x,y坐標的最快方法是什么?
 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM