1. 程式人生 > >[UVALive7261]A - Xiongnu's Land (二分)

[UVALive7261]A - Xiongnu's Land (二分)

while continue 大於 並且 輸出結果 net lan include !=

題目鏈接:https://vjudge.net/problem/UVALive-7261

題意略

三個步驟:

1.二分滿足左邊綠洲面積大於等於右邊綠洲面積,並且使左邊面積盡可能大的分割線位置。

2.判斷這個分割線是否包含於任何一個綠洲中,如果包含,那麽直接輸出結果就行,否則:

3.從此坐標向右掃描,找到下一個綠洲的左邊界,此為答案。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 typedef struct Sq { LL x, y, w, h; }Sq;
 6 const
int maxn = 10100; 7 LL n, k; 8 Sq sq[maxn]; 9 LL sum; 10 map<LL, int> vis; 11 12 bool ok1(LL val) { 13 LL a = 0; 14 for(int i = 0; i < k; i++) { 15 if(sq[i].x + sq[i].w <= val) a += sq[i].w * sq[i].h; 16 else if(sq[i].x <= val && val <= sq[i].x+sq[i].w) {
17 a += sq[i].h * (val - sq[i].x); 18 } 19 } 20 LL b = sum - a; 21 return a >= b; 22 } 23 24 int main() { 25 // freopen("in", "r", stdin); 26 int T; 27 LL x, y, w, h; 28 scanf("%d", &T); 29 while(T--) { 30 scanf("%lld%lld",&n,&k);
31 sum = 0; vis.clear(); 32 vis[n] = 1; 33 for(int i = 0; i < k; i++) { 34 scanf("%lld%lld%lld%lld",&x,&y,&w,&h); 35 sq[i] = Sq{x,y,w,h}; 36 vis[x] = 1; 37 sum += w * h; 38 } 39 LL lo = 0, hi = n; 40 LL ret = 0; 41 while(lo <= hi) { 42 LL mid = (lo + hi) >> 1; 43 if(ok1(mid)) { 44 ret = mid; 45 hi = mid - 1; 46 } 47 else lo = mid + 1; 48 } 49 bool flag = 0; 50 for(int i = 0; i < k; i++) { 51 if(sq[i].x <= ret && ret < sq[i].x+sq[i].w) { 52 flag = 1; 53 break; 54 } 55 } 56 if(flag) { 57 printf("%lld\n", ret); 58 continue; 59 } 60 LL remain = 0; 61 for(LL i = ret; i <= n; i++) { 62 if(vis.find(i) != vis.end()) { 63 remain = i - ret; 64 break; 65 } 66 } 67 printf("%lld\n", ret+remain); 68 } 69 return 0; 70 }

[UVALive7261]A - Xiongnu's Land (二分)