Sicily 1045 Space Management

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

Description

The new general manager Gill Bates has been to a seminar on time management. Ever since she has been bothering all of her staff to manage their own time. Now she plans to take it one step further: she wants to start managing her space too. And since she has also learned to start small, she wants to start by managing her desk space. Work tends to pile up on her desk, especially since the time management training where she was taught to order all documents in neat piles and organize her work accordingly. She now needs to calculate how much desk space is occupied. For this she comes up with a cunning plan. First, she orders her staff to measure the size and exact location of each document on the desk, in tenths of millimeters accuracy. As Gill is a very tidy person, all her document are completely on her desk, and are all perfectly aligned to the edges of the desk (i.e. the edges of all documents are parallel to an edge of the desk). For each document, the staff writes down the position of the lower left corner of the document and its size.
What you need to do now is to write a program that, given the input from the staff, calculates the occupied space on the desk. The maximum size of the desk is 2 * 1 meters. There is a maximum of 500 documents on the desk.

Input

The first line of the input consists of the number N of desks to be considered. Next follows for each desk the number of documents. Then follows for each document a separate line with 4 numbers: the smallest X and Y co-ordinates (i.e. the lower left corner), and the width and height of the document respectively.

Output

The output consists of N lines containing the amount of occupied space on each desk in squared tenths of millimeters.

Sample Input

2
2
0 0 1000 1000
0 0 1000 1000
3 
0 0 2 2 
2 2 2 2 
1 1 2 2

Sample Output

1000000
10

Solution

给定数个矩形的左下角和长宽,求这些矩形总共所占用的面积是多少,其中数据小于2000*1000。简单来说可以直接开数组,一个各格子用一个bool表示是否被占用,但是考虑双重循环,最大的运算量会是500*2000*1000,耗时太长。于是想到几天前接触到的一个离散化的方法,把已知的点投影的新的点上,做一个映射,根据已有的值重新排布坐标,再应用上述的bool矩阵表示是否被占用即可。注意对于映射之后,每一个格子的大小面积需要重新计算。

比如说原来是有两个点(0,0),(1000,1000),那么原来的坐标是x->(0,1,2,3,...,1000),映射之后就是(0,1000)只有两个点。预处理排序之后映射坐标,预处理每一个格子的面积,最后按点扫描,根据反馈结果累加求和即可。总体的复杂度就是点数的乘积。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

bool has[1005][1005], ending[1005]; //at most 1000 point
int toX[2005], toY[2005], s[1005][1005];
int px[1005], py[1005], ord[1005];

int cmpx(const int a, const int b) { return px[a] < px[b]; }
int cmpy(const int a, const int b) { return py[a] < py[b]; }

int main()
{
  int n;

  scanf("%d", &n);
  while (n--)
  {
    int m, x0, y0, x1, y1;
    memset(has, 0, sizeof has);

    scanf("%d", &m);
    for (int i = 0; i < m; ++i)
    {
      scanf("%d%d%d%d", &x0, &y0, &x1, &y1);
      x1 += x0;
      y1 += y0;
      px[i * 2] = x0; px[i * 2 + 1] = x1;
      py[i * 2] = y0; py[i * 2 + 1] = y1;
      ord[i * 2] = i * 2; ord[i * 2 + 1] = i * 2 + 1;
      ending[i * 2 + 1] = i * 2;
    }

    sort(ord, ord + 2 * m, cmpx);
    for (int i = 0; i < 2 * m; ++i) toX[i] = px[ord[i]], px[ord[i]] = i;
    sort(ord, ord + 2 * m, cmpy);
    for (int i = 0; i < 2 * m; ++i) toY[i] = py[ord[i]], py[ord[i]] = i;
    for (int i = 0; i < 2 * m-1; ++i)
    {
      for (int j = 0; j < 2 * m-1; ++j)
      {
        s[i][j] = (toX[i + 1] - toX[i]) * (toY[j + 1] - toY[j]);
      }
    }

    for (int p = 0; p < m; ++p)
    {
      int m = 2 * p;
      for (int i = px[m]; i < px[m + 1]; ++i)
        for (int j = py[m]; j < py[m + 1]; ++j) has[i][j] = true;
    }

    int ans = 0;
    for (int i = 0; i < 1005; ++i)
      for (int j = 0; j < 1005; ++j) if (has[i][j]) ans += s[i][j];

    printf("%d\n", ans);
  }

  return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值