c++矩形分割

题目描述
平面上有一个大矩形,其左下角坐标(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;
}

posted @ 2020-04-22 22:44  我为编程上架构  阅读(972)  评论(0编辑  收藏  举报