hihocoder 2015 北京区域赛 A Xiongnu's Land

  题目链接:https://vjudge.net/contest/162845#problem/A

  题目描述:一个正方形内有n个长方形, 从中间切一刀使两边的面积尽可能相等且左面大于等于右面, 输出一个整数表示切得坐标。

  解题思路:很明显的二分, 两次二分, 第一次二分使面积尽可能相等, 第二次使左面尽可能大于右面。

  代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;

const int MAXN = 10000 + 8;
#define ll long long
typedef struct {
    ll x;
    ll y;
    ll w;
    ll h;
}node;

node f[MAXN];
int n;

ll fun( ll x ) {
    ll temp = 0;
    for( int i = 0; i < n; i++ ) {
        temp += f[i].h*max( (ll)0, min( f[i].w, x - f[i].x));
    }
    
    return temp;
}
int main() {
    int t;
    scanf( "%d", &t );
    while( t-- ) {
        memset(f, 0, sizeof(f));
        ll R;
        scanf( "%lld", &R );
        scanf( "%d", &n );
        
        ll sum = 0;
        for( int i = 0; i < n; i++ ) {
            scanf( "%lld%lld%lld%lld", &f[i].x, &f[i].y, &f[i].w, &f[i].h );
            sum += f[i].w * f[i].h;
        }
        ll l, r;
        l = 0;
        r = R+1;
        ll mid;
        while( l < r ) {
            mid = (l+r)/2;
//            cout << mid << endl;
            if( 2*fun(mid) < sum ) {
                l = mid+1;
            }
            else {
                r = mid;
            }
//            cout << "===" << endl;
        }
//        cout << "r: " << r << endl;
        ll ans = fun( r );
        l = 0;
        r = R+1;
        while( l < r ) {
            mid = (l+r) / 2;
            if( fun(mid) <= ans ) {
                l = mid + 1;
            }
            else {
                r = mid;
            }
        }
        ll res = l - 1;
        printf( "%lld\n", res );
    }
    return 0;
}
View Code

  思考:首先自己的代码能力实在是太差, 虽然能看出来是二分但是实现还是十分的费劲, bug重重, 不多说, 多码。

原文地址:https://www.cnblogs.com/FriskyPuppy/p/6827114.html