题目链接: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; }
思考:首先自己的代码能力实在是太差, 虽然能看出来是二分但是实现还是十分的费劲, bug重重, 不多说, 多码。