題解 矩形分割(二分)

2021-10-03 04:53:42 字數 1954 閱讀 9570

平面上有乙個大矩形,其左下角座標(0,0),右上角座標(r,r)。大矩形內部包含一些小矩形,小矩形都平行於座標軸且互不重疊。所有矩形的頂點都是整點。要求畫一根平行於y軸的直線x=k(k是整數) ,使得這些小矩形落在直線左邊的面積必須大於等於落在右邊的面積,且兩邊面積之差最小。並且,要使得大矩形在直線左邊的的面積盡可能大。注意:若直線穿過乙個小矩形,將會把它切成兩個部分,分屬左右兩側。

第一行是整數r,表示大矩形的右上角座標是(r,r) (1 <= r <= 1,000,000)。

接下來的一行是整數n,表示一共有n個小矩形(0 < n <= 10000)。

再接下來有n 行。每行有4個整數,l,t, w 和 h, 表示有乙個小矩形的左上角座標是(l,t),寬度是w,高度是h (0<=l,t <= r, 0 < w,h <= r). 小矩形不會有位於大矩形之外的部分。

在講這道題之前,複習一下二分寫法:

while

(l < r)

或這樣:

while

(l < r)

這個寫法好處在於不用特判,l就是答案,強烈推薦

先讀題幹,有以下資訊:

s左 >= s右,要使s左 - s右 最小,且盡量靠右

怎麼算分割線下的差值,其實就是迴圈對每個矩形進行計算即可

那麼用什麼作為標準二分呢?怎麼用二分做!

二分適用於一段單調序列,如果我們計算每個分割線下的左右差值,應該是這樣:

這不符合二分,但是可以考慮用三分,找到最接近0的位置(相同則盡量靠右),若此時s左》=s右,直接輸出答案;若s左然而遺憾的是:這個函式有很多值相等,我們不知道是位於同側還是位於異側,無法確定範圍,所以三分不可行。

思路二:我們用s左-s右作關鍵字,發現s左-s右是從左往右單調不嚴格遞增!

進一步,定義乙個函式計算f(n)=s左-s右,n是分割線位置,我們取的是f(n)>= 0且最小的那個值

注意:在滿足最小的情況下盡量靠右!

核心**:

while

(l

然而這種二分到最後可能會卡死,自己想!

偽**:

struct jx

int/

bool

check()

intmain()

二分;輸出;

}

//二分

#include

#include

#define ll long long

using

namespace std;

const

int maxn=

1e5+5;

ll r,n,l,t,w,h,ans,sum;

struct jxa[maxn]

;ll check

(ll x)

else

if(a[i]

.tail>=x&&a[i]

.head<=x)

else

if(a[i]

.head>=x)

}return sum1-sum2;

}int

main()

ll l=

0,r=sum;

while

(l+1

check

(l)>=0&&

check

(l)<

check

(r)) ans=l;

else ans=r;

printf

("%lld"

,ans)

;}

矩形分割(二分)

描述 平面上有乙個大矩形,其左下角座標 0,0 右上角座標 r,r 大矩形內部包含一些小矩形,小矩形都平行於座標軸且互不重疊。所有矩形的頂點都是整點。要求畫一根平行於y軸的直線x k k是整數 使得這些小矩形落在直線左邊的面積必須大於等於落在右邊的面積,且兩邊面積之差最小。並且,要使得大矩形在直線左...

OpenJudge 矩形分割 (二分查詢)

03 矩形分割 總時間限制 1000ms 記憶體限制 65536kb 描述 平面上有乙個大矩形,其左下角座標 0,0 右上角座標 r,r 大矩形內部包含一些小矩形,小矩形都平行於座標軸且互不重疊。所有矩形的頂點都是整點。要求畫一根平行於y軸的直線x k k是整數 使得這些小矩形落在直線左邊的面積必須...

4136 矩形分割(二分查詢)

總時間限制 1000ms 記憶體限制 65536kb 描述平面上有乙個大矩形,其左下角座標 0,0 右上角座標 r,r 大矩形內部包含一些小矩形,小矩形都平行於座標軸且互不重疊。所有矩形的頂點都是整點。要求畫一根平行於y軸的直線x k k是整數 使得這些小矩形落在直線左邊的面積必須大於等於落在右邊的...