• 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;
    }

  • 相关阅读:
    Retrofit2源码分析
    Android8.0硬件加速的重绘流程
    Android单元测试
    rand5->rand7,rand7->rand10
    快速排序的随机化版本
    快速排序
    亦或实现交换
    在最坏情况下,找到n个元素中第二小的元素需要n+lgn-2次比较
    3*n/2时间内求出最大最小值
    基数排序
  • 原文地址:https://www.cnblogs.com/xufeng123/p/12757488.html
Copyright © 2020-2023  润新知