zoukankan      html  css  js  c++  java
  • poj 1689 && zoj 1422 3002 Rubbery (Geometry + BFS)

    ZOJ :: Problems :: Show Problem

    1689 -- 3002 Rubbery

      这题是从校内oj的几何分类里面找到的。

      题意不难,就是给出一个区域(L,W),这个区域里面有很多多边形,多边形的边都是和x/y轴平行的。一个射线源在(L,0),射线是走平行于x/y轴的路径的。它们可以贴着多边形的边经过,不过不能穿过区域中的多边形,甚至不能从有至少一个交点的两条边之间穿过(区域边沿也一样)。射线只能向着x减少或者y增大的方向行走,问有多大的区域是没有射线经过的,不包括多边形区域。

      做法就是,先将区域离散化成若干矩形,然后将每一个矩形看成一个点,构出图以后bfs射线就可以了。最后统计没有射线经过的区域大小即可。

      做的时候注意,数组大小要控制好。如果射线源的位置在开始的时候就被覆盖了,可以直接计算没有多边形覆盖的面积。

    代码如下:

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <vector>
      6 #include <map>
      7 
      8 using namespace std;
      9 
     10 const int N = 55;
     11 const int M = N * N;
     12 map<int, int> xid, yid;
     13 bool blx[M >> 1][M >> 1], vis[M >> 1][M >> 1];
     14 typedef long long LL;
     15 typedef pair<int, int> PII;
     16 
     17 int L, W;
     18 int rx[M], ry[M], xn, yn, pn[N];
     19 PII poly[N][N];
     20 
     21 void fix(int id) {
     22     int mk = 0;
     23     for (int i = 0; i < pn[id]; i++) if (poly[id][mk] < poly[id][i]) mk = i;
     24     rotate(poly[id], poly[id] + mk, poly[id] + pn[id]);
     25 }
     26 
     27 const int dx[5] = { -1, -1, 0, 1, 0};
     28 const int dy[5] = { 1, 0, 1, 0, -1};
     29 
     30 inline LL cross(PII a, PII b) { return (LL) a.first * b.second - (LL) a.second * b.first;}
     31 PII operator - (PII a, PII b) { return PII(a.first - b.first, a.second - b.second);}
     32 
     33 bool inPoly(PII pt, int id) {
     34     int wn = 0;
     35     poly[id][pn[id]] = poly[id][0];
     36     for (int i = 0; i < pn[id]; i++) {
     37         LL k = cross(poly[id][i + 1] - poly[id][i], pt - poly[id][i]);
     38         int d1 = poly[id][i].second - pt.second;
     39         int d2 = poly[id][i + 1].second - pt.second;
     40         if (k > 0 && d1 <= 0 && d2 > 0) wn++;
     41         if (k < 0 && d2 <= 0 && d1 > 0) wn--;
     42     }
     43     return wn != 0;
     44 }
     45 
     46 int qx[M * M >> 2], qy[M * M >> 2];
     47 inline bool inMat(int x, int y) { return 0 <= x && x < xn && 0 <= y && y < yn;}
     48 
     49 void fill(int id) {
     50     int cx = xid[poly[id][0].first] - 1;
     51     int cy = yid[poly[id][0].second] - 1;
     52     blx[cx][cy] = true;
     53     int qh, qt, nx, ny;
     54     qh = qt = 0;
     55     qx[qt] = cx, qy[qt++] = cy;
     56     while (qh < qt) {
     57         cx = qx[qh], cy = qy[qh++];
     58         for (int i = 1; i < 5; i++) {
     59             nx = cx + dx[i], ny = cy + dy[i];
     60             if (inMat(nx, ny) && !blx[nx][ny] && inPoly(PII(rx[nx] + rx[nx + 1] >> 1, ry[ny] + ry[ny + 1] >> 1), id)) {
     61                 blx[nx][ny] = true;
     62                 qx[qt] = nx, qy[qt++] = ny;
     63             }
     64         }
     65     }
     66 }
     67 
     68 LL work(int n) {
     69     int cx = xn - 1, cy = 0;
     70     LL sum = 0;
     71     int qh, qt, nx, ny;
     72     memset(vis, 0, sizeof(vis));
     73     qh = qt = 0;
     74     if (!blx[cx][cy]) {
     75         qx[qt] = cx, qy[qt++] = cy;
     76         vis[cx][cy] = true;
     77     }
     78     while (qh < qt) {
     79         cx = qx[qh], cy = qy[qh++];
     80         for (int i = 1; i < 3; i++) {
     81             nx = cx + dx[i], ny = cy + dy[i];
     82             if (inMat(nx, ny) && !blx[nx][ny] && !vis[nx][ny]) {
     83                 vis[nx][ny] = true;
     84                 qx[qt] = nx, qy[qt++] = ny;
     85             }
     86         }
     87     }
     88     for (int i = 0; i < xn; i++) {
     89         for (int j = 0; j < yn; j++) {
     90             if (vis[i][j] || blx[i][j]) continue;
     91             sum += (LL) (rx[i + 1] - rx[i]) * (ry[j + 1] - ry[j]);
     92         }
     93     }
     94 //    for (int j = 0; j < yn; j++) {
     95 //        for (int i = 0; i < xn; i++) printf("%d", !vis[i][j] && !blx[i][j]);
     96 //        puts("");
     97 //    }
     98 //    cout << "sum " << sum << endl;
     99     return sum >> 2;
    100 }
    101 
    102 void PRE(int n) {
    103     sort(rx, rx + xn);
    104     xn = unique(rx, rx + xn) - rx;
    105     xid.clear();
    106     for (int i = 0; i < xn; i++) xid[rx[i]] = i;
    107     sort(ry, ry + yn);
    108     yn = unique(ry, ry + yn) - ry;
    109     yid.clear();
    110     for (int i = 0; i < yn; i++) yid[ry[i]] = i;
    111     xn--, yn--;
    112 //    for (int i = 0; i < xn; i++) cout << i << '~' << rx[i] << endl;
    113 //    for (int i = 0; i < yn; i++) cout << i << '-' << ry[i] << endl;
    114 //    cout << xn << ' ' << yn << endl;
    115     memset(blx, 0, sizeof(blx));
    116     for (int i = 0; i < n; i++) fix(i);
    117 //    for (int i = 0; i < pn[0]; i++) cout << poly[0][i].first << ' ' << poly[0][i].second << endl;
    118     for (int i = 0; i < n; i++) fill(i);
    119 //    for (int j = 0; j < yn; j++) {
    120 //        for (int i = 0; i < xn; i++) printf("%d", blx[i][j]);
    121 //        puts("");
    122 //    }
    123 }
    124 
    125 int main() {
    126 //    freopen("in", "r", stdin);
    127     int T, n, x, y;
    128     cin >> T;
    129     while (T-- && cin >> L >> W) {
    130         xn = yn = 0;
    131         L <<= 1, W <<= 1;
    132         rx[xn++] = L, ry[yn++] = W;
    133         rx[xn++] = 0, ry[yn++] = 0;
    134         cin >> n;
    135         for (int i = 0; i < n; i++) {
    136             cin >> pn[i];
    137             for (int j = 0; j < pn[i]; j++) {
    138                 scanf("%d%d", &poly[i][j].first, &poly[i][j].second);
    139                 poly[i][j].first <<= 1, poly[i][j].second <<= 1;
    140                 rx[xn++] = poly[i][j].first, ry[yn++] = poly[i][j].second;
    141             }
    142         }
    143         PRE(n);
    144         cout << work(n) << endl;
    145     }
    146     return 0;
    147 }
    148 
    149 /*
    150 10
    151 12 8
    152 3
    153 8 5 1 11 1 11 5 7 5 7 4 9 4 9 2 5 2
    154 4 0 3 3 3 3 4 0 4
    155 4 1 4 2 4 2 6 1 6
    156 10 10
    157 3
    158 4 1 1 5 1 5 5 1 5
    159 4 5 3 9 3 9 8 5 8
    160 4 0 5 1 5 1 4 0 4
    161 10 10
    162 1
    163 10 1 1 1 4 0 4 0 5 5 5 5 8 9 8 9 3 5 3 5 1
    164 10 10
    165 1
    166 10 1 1 5 1 5 3 9 3 9 8 5 8 5 5 0 5 0 4 1 4
    167 1000000 1000000
    168 1
    169 8 1 1 1 999999 2 999999 2 999998 999998 999998 999998 999999 999999 999999 999999 1
    170 1000000 1000000
    171 1
    172 8 1 1 1 999999 2 999999 2 2 999998 2 999998 999999 999999 999999 999999 1
    173 1000000 1000000
    174 3
    175 6 1 1 1 999999 2 999999 2 2 999999 2 999999 1
    176 4 3 2 3 1000000 4 1000000 4 2
    177 4 5 2 5 999999 6 999999 6 2
    178 1000000 1000000
    179 4
    180 6 1 1 1 999999 2 999999 2 2 999999 2 999999 1
    181 4 3 2 3 1000000 4 1000000 4 2
    182 4 5 2 5 999999 6 999999 6 2
    183 4 6 999999 7 999999 7 1000000 6 1000000
    184 1000000 1000000
    185 5
    186 6 1 1 1 999999 2 999999 2 2 999999 2 999999 1
    187 4 3 2 3 1000000 4 1000000 4 2
    188 4 5 2 5 999999 6 999999 6 2
    189 4 6 999999 7 999999 7 1000000 6 1000000
    190 4 999999 1 999999 2 1000000 2 1000000 1
    191 1000000 1000000
    192 3
    193 6 1 1 1 999999 2 999999 2 2 999998 2 999998 1
    194 4 999999 3 999999 4 1000000 4 1000000 3
    195 4 999999 3 999999 2 999998 2 999998 3
    196 */
    View Code

      做题最蛋疼的事情不能理解透题目的意思。做这题的时候,自己不停的出数据坑自己,可是出到那么恶心了都找不到bug。以后还要更加注意细节!

    ——written by Lyon

  • 相关阅读:
    ADO 缓存更新
    DBNavigator中把insert变为append
    JQuery 选择器
    VS2013默认打开HTML文件没有设计视图
    windows 关机 重启 命令
    java如何计算两个日期之间相差多少天?
    java的list集合操作List<T>转化List<Long>
    ExcelUtil工具类
    oracle的START WITH CONNECT BY PRIOR用法
    oracle的with as用法
  • 原文地址:https://www.cnblogs.com/LyonLys/p/poj_1689_zoj_1422_Lyon.html
Copyright © 2011-2022 走看看