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

转载于:https://www.cnblogs.com/LyonLys/p/poj_1689_zoj_1422_Lyon.html

poj 1689 zoj 1422 3002 Rubbery (Geometry + BFS)相关推荐

  1. POJ,ZOJ题目分类(多篇整合版,分类很细致,全面)

    水题: 3299,2159,2739,1083,2262,1503,3006,2255,3094 初级: 一.基本算法:        (1)枚举 (1753,2965)       (2)贪心(13 ...

  2. poj 3038 Children of the Candy Corn bfs dfs

    http://poj.org/problem?id=3083 入口S,出口E,分别求由入口 到出口靠左走,靠右走,和最短路三种走法各自的步数.入口和出口在边界处,并且不会在四个角上,入口和出口至少隔着 ...

  3. poj 3487 zoj 1576 稳定婚姻

    两题都是基础题,不同的是 zoj 那题的男女可能重名. Gale-Shapley 算法: while ( 存在男人m是自由的 ) { 令w是m的还没求过婚的最高排名的女人 if ( w是自由的 )   ...

  4. POJ 2777 ZOJ 1610 HDU 1698 --线段树--区间更新

    直接将这3题 放一起了  今天在做线段树的东西 这3个都是区间更新的 查询方式互相不同 反正都可以放到一起吧 直接先上链接了 touch me touch me touch me 关于涉及到区间的修改 ...

  5. POJ 2243:Knight Moves(双向BFS)

    http://poj.org/problem?id=2243 问题概述:一个8*8的棋盘,给定一个起点(列a-h,行1-8)和一个终点(列a-h,行1-8),按骑士的走法(走日字),从起点到 终点最少 ...

  6. poj 1436 zoj 1391 Horizontally Visible Segments (Segment Tree)

    ZOJ :: Problems :: Show Problem 1436 -- Horizontally Visible Segments 用线段树记录表面能被看见的线段的编号,然后覆盖的时候同时把能 ...

  7. UVA 413|LA 5388|POJ 1492|ZOJ 1338 Up and Down Sequences

    https://zoj.pintia.cn/problem-sets/91827364500/problems/91827364837 题意:如果是上升序列,上升序列的长度不是所有上升数字的,是这么规 ...

  8. POJ 2240 ZOJ 1082 Arbitrage 最短路,c++ stl pass g++ tle 难度:0

    http://poj.org/problem?id=2240 用log化乘法为加法找正圈 c++ 110ms,g++tle #include <string> #include <m ...

  9. poj 2096 , zoj 3329 , hdu 4035 —— 期望DP

    题目:http://poj.org/problem?id=2096 题目好长...意思就是每次出现 x 和 y,问期望几次 x 集齐 n 种,y 集齐 s 种: 所以设 f[i][j] 表示已经有几种 ...

最新文章

  1. migration vmware vms to openstack kvm 修改vmware windows scsi to ide
  2. 知识点二、PHP简单的分页过程与原理
  3. Oracle dblink报错:ORA-01017、ORA-02063解决
  4. linux内核imx6,imx6ull之linux内核移植
  5. linux mysql5.7.18多实例_mysql5.7.13二进制包安装多实例
  6. Python语言三种优点。
  7. python 反编译exe
  8. 软件项目需求开发过程实践之软件需求说明书
  9. TDD测试驱动开发案例【水货】
  10. 网络测速神器:SpeedTest深度指南
  11. 新唐NUC980网络设置
  12. 关闭wps2019的屏保功能
  13. 读书笔记:收敛性 ← 随机过程
  14. 最受IT公司欢迎的 30 款开源软件
  15. 一笔画问题 nyist42
  16. basler工业相机使用问题总结
  17. 【操作系统】alios
  18. 老板电器:坏账与乌龙齐飞,主业难保新增长
  19. VMware Workstation Pro 16 虚拟机下载安装
  20. 科视Christie集成式视听方案升级“飞行影院”全景沉浸体验

热门文章

  1. 微信小程序----使用微信内置地图查看位置wx.openLocation(Object object)
  2. observable.map 介绍
  3. 赠与今年的大学毕业生
  4. Safari无痕浏览影响localStorage
  5. C# 打开指定目录并定位到文件
  6. 如何将英文文献转中文?
  7. python学习笔记(一)PIP
  8. AXD 在win7 vista下 启动失败
  9. darknet-配置参数burn-in
  10. 阿里支付宝api对银行卡进行效验