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
转载于:https://www.cnblogs.com/LyonLys/p/poj_1689_zoj_1422_Lyon.html
poj 1689 zoj 1422 3002 Rubbery (Geometry + BFS)相关推荐
- POJ,ZOJ题目分类(多篇整合版,分类很细致,全面)
水题: 3299,2159,2739,1083,2262,1503,3006,2255,3094 初级: 一.基本算法: (1)枚举 (1753,2965) (2)贪心(13 ...
- poj 3038 Children of the Candy Corn bfs dfs
http://poj.org/problem?id=3083 入口S,出口E,分别求由入口 到出口靠左走,靠右走,和最短路三种走法各自的步数.入口和出口在边界处,并且不会在四个角上,入口和出口至少隔着 ...
- poj 3487 zoj 1576 稳定婚姻
两题都是基础题,不同的是 zoj 那题的男女可能重名. Gale-Shapley 算法: while ( 存在男人m是自由的 ) { 令w是m的还没求过婚的最高排名的女人 if ( w是自由的 ) ...
- POJ 2777 ZOJ 1610 HDU 1698 --线段树--区间更新
直接将这3题 放一起了 今天在做线段树的东西 这3个都是区间更新的 查询方式互相不同 反正都可以放到一起吧 直接先上链接了 touch me touch me touch me 关于涉及到区间的修改 ...
- POJ 2243:Knight Moves(双向BFS)
http://poj.org/problem?id=2243 问题概述:一个8*8的棋盘,给定一个起点(列a-h,行1-8)和一个终点(列a-h,行1-8),按骑士的走法(走日字),从起点到 终点最少 ...
- poj 1436 zoj 1391 Horizontally Visible Segments (Segment Tree)
ZOJ :: Problems :: Show Problem 1436 -- Horizontally Visible Segments 用线段树记录表面能被看见的线段的编号,然后覆盖的时候同时把能 ...
- UVA 413|LA 5388|POJ 1492|ZOJ 1338 Up and Down Sequences
https://zoj.pintia.cn/problem-sets/91827364500/problems/91827364837 题意:如果是上升序列,上升序列的长度不是所有上升数字的,是这么规 ...
- 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 ...
- poj 2096 , zoj 3329 , hdu 4035 —— 期望DP
题目:http://poj.org/problem?id=2096 题目好长...意思就是每次出现 x 和 y,问期望几次 x 集齐 n 种,y 集齐 s 种: 所以设 f[i][j] 表示已经有几种 ...
最新文章
- migration vmware vms to openstack kvm 修改vmware windows scsi to ide
- 知识点二、PHP简单的分页过程与原理
- Oracle dblink报错:ORA-01017、ORA-02063解决
- linux内核imx6,imx6ull之linux内核移植
- linux mysql5.7.18多实例_mysql5.7.13二进制包安装多实例
- Python语言三种优点。
- python 反编译exe
- 软件项目需求开发过程实践之软件需求说明书
- TDD测试驱动开发案例【水货】
- 网络测速神器:SpeedTest深度指南
- 新唐NUC980网络设置
- 关闭wps2019的屏保功能
- 读书笔记:收敛性 ← 随机过程
- 最受IT公司欢迎的 30 款开源软件
- 一笔画问题 nyist42
- basler工业相机使用问题总结
- 【操作系统】alios
- 老板电器:坏账与乌龙齐飞,主业难保新增长
- VMware Workstation Pro 16 虚拟机下载安装
- 科视Christie集成式视听方案升级“飞行影院”全景沉浸体验