a097: PARKET

Tags: math


出處:https://zerojudge.tw/ShowProblem?problemid=a097
提交:https://zerojudge.tw/Submissions?problemid=a097&account=allllllan123456


問題:考慮一個只用 1 x 1 磁磚組成的地板,令其長為 $L$、寬為 $W$,已知它可以分成邊框 (灰色、總面積 $B$ 單位) 與內部 (黑色、總面積 $R$ 單位) 兩部分,而且邊框四個方向的寬度都要一樣。現在請你在只給定 $B,R\in[1,2^{30}]$ 的條件之下,找到一組 $L$ 和 $W$ 差距最大的解 (一定存在)。


解法:令邊框的寬度為 $x$,則我們有兩式:$\begin{cases}l\cdot w=R\\(l+2x)\cdot(w+2x)=R+B\end{cases}$,一個簡便的方法是從第一式裡面的 $w=1$ 開始往上嘗試依序找到可能的 $(l,w)$,每找到一組就立馬丟進第二式解一元二次找 $x=\dfrac{-(l+w) \pm \sqrt{(l+w)^2 + 4B}}4$ (負不合),如果 $x$ 是正整數,則此時的 $(L,W)=(l+2x, w+2x)$ 為一合法解,程序立刻中止。


 1#include <bits/stdc++.h>
 2using namespace std;
 3
 4int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); // IO 優化
 5    long long B, R; /* avoid overflowed R+B, 4B */
 6    while (cin >> B >> R) { assert(B>0 && R>0);
 7        int sqrtR = sqrt(R);
 8        for (int w=1; w<=sqrtR; w++)
 9            if (R % w == 0) {
10                int l = R / w;
11                /* (l+2x)(w+2x) = R+B
12                *  4x^2 + 2(l+w)x + l*w - (R+B) = 0
13                *  x = (-2(l+w) + sqrt(4*(l+w)^2 - 4*4*(l*w-(R+B)))) / 8
14                *  x = (-(l+w) + sqrt((l+w)^2 - 4*(l*w-(R+B)))) / 4
15                *  x = (-(l+w) + sqrt((l+w)^2 + 4B)) / 4
16                */
17                int x = (-(l+w) + sqrt((l+w)*(l+w) + 4*B)) / 4;
18                if ((l+2*x) * (w+2*x) == R+B) {
19                    cout << l+2*x << ' ' << w+2*x << '\n';
20                    break;
21                }
22            }
23    }
24    return 0;
25}

no image