• [UVALive7261]A


    题目链接: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
    ", 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
    ", ret+remain);
    68     }
    69     return 0;
    70 }
  • 相关阅读:
    Kaka's Matrix Travels
    Cable TV Network
    LightOJ 1137
    SPOJ AMR11E Distinct Primes 基础数论
    HDU 5533Dancing Stars on Me 基础几何
    POJ 1014 / HDU 1059 Dividing 多重背包+二进制分解
    vijos 1180 选课 树形DP
    vijos 1313 金明的预算方案 树形DP
    LightOJ 1062
    vijos 1464 积木游戏 DP
  • 原文地址:https://www.cnblogs.com/kirai/p/6822624.html
Copyright © 2020-2023  润新知