题目描述 平面上有一个大矩形,其左下角坐标(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). 小矩形不会有位于大矩形之外的部分。
输出 输出整数n,表示答案应该是直线 x=n。如果必要的话,x=R也可以是答案。
样例输入 1000 2 1 1 2 1 5 1 2 1
样例输出 5
#include <iostream>
#include <cassert>
#include <vector>
#include <map>
#include <iterator>
using namespace std;
class Rectangle { public: int L; // top left x int T; // top left y int W; // width int H; // height };
int main() { const int MAX_R = 1000000; const int MAX_N = 10000; vector<Rectangle> rect_vec; int R, N;
cin >> R;
assert(R>=1 && R<=MAX_R);
cin >> N;
assert(N>=0 && N<=MAX_N); // ??
if (N <= 1) { cout << R << endl; return 0; }
Rectangle rec; int min_x = R; int max_x = 0; for (int n=1; n<=N; n++) { cin >> rec.L >> rec.T >> rec.W >> rec.H; rect_vec.push_back(rec);
min_x = min(rec.L, min_x); max_x = max(rec.L+rec.W, max_x); }
int Sl; // left square of line x = k int Sr; // right square of line x = k map<int, int> Sdiff_k_map;
for (int k=min_x; k<=max_x; k++) { Sl = 0; Sr = 0; for (int i=0; i<N; i++) { if (k <= rect_vec[i].L) { Sl += 0; Sr += rect_vec[i].W * rect_vec[i].H; } else if(k >= rect_vec[i].L+rect_vec[i].W) { Sl += rect_vec[i].W * rect_vec[i].H; Sr += 0; } else if (k > rect_vec[i].L && k < rect_vec[i].L+rect_vec[i].W) { Sl += (k - rect_vec[i].L) * rect_vec[i].H; Sr += (rect_vec[i].L+rect_vec[i].W - k) * rect_vec[i].H; } } Sdiff_k_map[Sl-Sr] = k; }
map<int, int>::iterator iter; for(iter=Sdiff_k_map.begin(); iter!=Sdiff_k_map.end(); iter++) { if (iter->first >= 0) { cout << iter->second << endl; break; } }
return 0; }
|
请发表评论