zoukankan      html  css  js  c++  java
  • AOJ 0531 坐标离散化

    涂色:(日文题目,自己翻译成了中文)为了宣传信息竞赛,要在长方形的三合板上喷油漆来制作招牌。三合板上不需要涂色的部分预先贴好了护板。被护板隔开的区域要涂上不同的颜色,比如上图就应该涂上5种颜色。

    请编写一个程序计算涂色数量,输入数据中,保证看板不会被护板全部遮住,并且护板的边一定是水平或垂直的。

    输入:

    第一个数是宽w(1 ≤ w ≤ 1000000),第二个数是高h(1 ≤ h ≤ 1000000)。

    第二行是护板的数量n(1 ≤ n ≤ 1000),接着n行是每个护板的左下角坐标 (x1 , y1 )和右上角坐标 (x2 , y2 ),用空格隔开: x1 , y1 , x2 , y2 (0 ≤ x1< x2 ≤ w, 0 ≤ y1 < y2 ≤ h 都是整数)

    招牌的坐标系如下,左下角是 (0, 0) ,右上角是(w, h) , 测试集中的30%都满足w ≤ 100, h ≤ 100, n ≤ 100。

    输出:

    一个整数,代表涂色数量。

    使用坐标离散化求解。

     坐标离散化的思想是:当坐标范围很大而坐标数量很少时,可以考虑把所有用到的横坐标排序,然后用每个坐标对应的下标来更新坐标位置。

    举例来说:

    这个例子中的用到的横坐标有1,2,4,5,6,7,9,10,11,12,13,14。

    那么横坐标对(1,5)就可以转化为(0,3)。节省了一位空间,这个节省在空隙变大后会越来越明显。

    通过坐标离散化,通常时间复杂度就可以降到令人满意的程度了。

    这里使用了imos法,进一步优化时间复杂度。

    接下来是代码,来自http://www.hankcs.com/program/algorithm/aoj-0531-paint-color.html

      1 #include<iostream>
      2 #include<vector>
      3 #include<algorithm>
      4 #include<queue>
      5 #include <cstring>
      6 #define MAX_N 1000 + 16
      7  
      8 using namespace std;
      9  
     10 int N, H, W;
     11 int X1[MAX_N], X2[MAX_N], Y1[MAX_N], Y2[MAX_N];
     12 int fld[2 * MAX_N][2 * MAX_N], // 填充遍历用,代表坐标(i, j)处是否空白(压缩后)
     13 dx[4] = { 1, -1, 0, 0 }, dy[4] = { 0, 0, 1, -1 };
     14  
     15 // 压缩坐标,将坐标的值变成“这是第几种值”,返回一共有几种坐标
     16 int compress(int *x1, int *x2, int w)
     17 {
     18     vector<int>xs;
     19  
     20     for (int i = 0; i < N; ++i)
     21     {
     22         int tx1 = x1[i], tx2 = x2[i];
     23         if (1 <= tx1 && tx1 < w) xs.push_back(tx1);
     24         if (1 <= tx2 && tx2 < w) xs.push_back(tx2);
     25     }
     26     xs.push_back(0);
     27     xs.push_back(w);
     28     sort(xs.begin(), xs.end());
     29     xs.erase(unique(xs.begin(), xs.end()), xs.end());
     30     for (int i = 0; i < N; ++i)
     31     {
     32         x1[i] = find(xs.begin(), xs.end(), x1[i]) - xs.begin();
     33         x2[i] = find(xs.begin(), xs.end(), x2[i]) - xs.begin();
     34     }
     35     return xs.size() - 1;
     36 }
     37  
     38 int bfs()
     39 {
     40     int ans = 0;
     41     for (int i = 0; i < H; ++i)
     42     {
     43         for (int j = 0; j < W; ++j)
     44         {
     45             if (fld[i][j]) continue;
     46             ++ans;
     47             queue<pair<int, int> >que;
     48             que.push(make_pair(j, i));
     49             while (!que.empty())
     50             {
     51                 int nx = que.front().first, ny = que.front().second;
     52                 que.pop();
     53  
     54                 for (int i = 0; i < 4; ++i)
     55                 {
     56                     int tx = nx + dx[i], ty = ny + dy[i];
     57                     if (tx < 0 || W < tx || ty < 0 || H< ty || fld[ty][tx] > 0) continue;
     58                     que.push(make_pair(tx, ty));
     59                     fld[ty][tx] = 1;
     60                 }
     61             }
     62         }
     63     }
     64     return ans;
     65 }
     66  
     67 ///////////////////////////SubMain//////////////////////////////////
     68 int main(int argc, char *argv[])
     69 {
     70     while (cin >> W >> H, W | H)
     71     {
     72         cin >> N;
     73         for (int i = 0; i < N; ++i)
     74         {
     75             cin >> X1[i] >> Y1[i] >> X2[i] >> Y2[i];
     76         }
     77  
     78         memset(fld, 0, sizeof(fld));
     79  
     80         W = compress(X1, X2, W);
     81         H = compress(Y1, Y2, H);
     82  
     83         // imos-法
     84         for (int i = 0; i < N; i++)
     85         {
     86             fld[Y1[i]][X1[i]]++;
     87             fld[Y1[i]][X2[i]]--;
     88             fld[Y2[i]][X1[i]]--;
     89             fld[Y2[i]][X2[i]]++;
     90         }
     91         // 横向累积
     92         for (int i = 0; i < H; i++)
     93         {
     94             for (int j = 1; j < W; j++)
     95             {
     96                 fld[i][j] += fld[i][j - 1];
     97             }
     98         }
     99         // 纵向累积
    100         for (int i = 1; i < H; i++)
    101         {
    102             for (int j = 0; j < W; j++)
    103             {
    104                 fld[i][j] += fld[i - 1][j];
    105             }
    106         }// 累积完后,fld中非0部分表示有挡板
    107         cout << bfs() << endl;
    108     }
    109     return 0;
    110 }
    111 ///////////////////////////End Sub//////////////////////////////////
    View Code
  • 相关阅读:
    Proj THUDBFuzz Paper Reading: The Art, Science, and Engineering of Fuzzing: A Survey
    Proj THUDBFuzz Paper Reading: A systematic review of fuzzing based on machine learning techniques
    9.3 付费代理的使用
    11.1 Charles 的使用
    第十一章 APP 的爬取
    10.2 Cookies 池的搭建
    10.1 模拟登录并爬取 GitHub
    11.5 Appium 爬取微信朋友圈
    11.4 Appium 的基本使用
    11.3 mitmdump 爬取 “得到” App 电子书信息
  • 原文地址:https://www.cnblogs.com/bestefforts/p/8987538.html
Copyright © 2011-2022 走看看