poj 1689 && zoj 1422 3002 Rubbery (Geometry + BFS)
ZOJ :: Problems :: Show Problem
这题是从校内oj的几何分类里面找到的。
题意不难,就是给出一个区域(L,W),这个区域里面有很多多边形,多边形的边都是和x/y轴平行的。一个射线源在(L,0),射线是走平行于x/y轴的路径的。它们可以贴着多边形的边经过,不过不能穿过区域中的多边形,甚至不能从有至少一个交点的两条边之间穿过(区域边沿也一样)。射线只能向着x减少或者y增大的方向行走,问有多大的区域是没有射线经过的,不包括多边形区域。
做法就是,先将区域离散化成若干矩形,然后将每一个矩形看成一个点,构出图以后bfs射线就可以了。最后统计没有射线经过的区域大小即可。
做的时候注意,数组大小要控制好。如果射线源的位置在开始的时候就被覆盖了,可以直接计算没有多边形覆盖的面积。
代码如下:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map> using namespace std; const int N = ;
const int M = N * N;
map<int, int> xid, yid;
bool blx[M >> ][M >> ], vis[M >> ][M >> ];
typedef long long LL;
typedef pair<int, int> PII; int L, W;
int rx[M], ry[M], xn, yn, pn[N];
PII poly[N][N]; void fix(int id) {
int mk = ;
for (int i = ; i < pn[id]; i++) if (poly[id][mk] < poly[id][i]) mk = i;
rotate(poly[id], poly[id] + mk, poly[id] + pn[id]);
} const int dx[] = { -, -, , , };
const int dy[] = { , , , , -}; inline LL cross(PII a, PII b) { return (LL) a.first * b.second - (LL) a.second * b.first;}
PII operator - (PII a, PII b) { return PII(a.first - b.first, a.second - b.second);} bool inPoly(PII pt, int id) {
int wn = ;
poly[id][pn[id]] = poly[id][];
for (int i = ; i < pn[id]; i++) {
LL k = cross(poly[id][i + ] - poly[id][i], pt - poly[id][i]);
int d1 = poly[id][i].second - pt.second;
int d2 = poly[id][i + ].second - pt.second;
if (k > && d1 <= && d2 > ) wn++;
if (k < && d2 <= && d1 > ) wn--;
}
return wn != ;
} int qx[M * M >> ], qy[M * M >> ];
inline bool inMat(int x, int y) { return <= x && x < xn && <= y && y < yn;} void fill(int id) {
int cx = xid[poly[id][].first] - ;
int cy = yid[poly[id][].second] - ;
blx[cx][cy] = true;
int qh, qt, nx, ny;
qh = qt = ;
qx[qt] = cx, qy[qt++] = cy;
while (qh < qt) {
cx = qx[qh], cy = qy[qh++];
for (int i = ; i < ; i++) {
nx = cx + dx[i], ny = cy + dy[i];
if (inMat(nx, ny) && !blx[nx][ny] && inPoly(PII(rx[nx] + rx[nx + ] >> , ry[ny] + ry[ny + ] >> ), id)) {
blx[nx][ny] = true;
qx[qt] = nx, qy[qt++] = ny;
}
}
}
} LL work(int n) {
int cx = xn - , cy = ;
LL sum = ;
int qh, qt, nx, ny;
memset(vis, , sizeof(vis));
qh = qt = ;
if (!blx[cx][cy]) {
qx[qt] = cx, qy[qt++] = cy;
vis[cx][cy] = true;
}
while (qh < qt) {
cx = qx[qh], cy = qy[qh++];
for (int i = ; i < ; i++) {
nx = cx + dx[i], ny = cy + dy[i];
if (inMat(nx, ny) && !blx[nx][ny] && !vis[nx][ny]) {
vis[nx][ny] = true;
qx[qt] = nx, qy[qt++] = ny;
}
}
}
for (int i = ; i < xn; i++) {
for (int j = ; j < yn; j++) {
if (vis[i][j] || blx[i][j]) continue;
sum += (LL) (rx[i + ] - rx[i]) * (ry[j + ] - ry[j]);
}
}
// for (int j = 0; j < yn; j++) {
// for (int i = 0; i < xn; i++) printf("%d", !vis[i][j] && !blx[i][j]);
// puts("");
// }
// cout << "sum " << sum << endl;
return sum >> ;
} void PRE(int n) {
sort(rx, rx + xn);
xn = unique(rx, rx + xn) - rx;
xid.clear();
for (int i = ; i < xn; i++) xid[rx[i]] = i;
sort(ry, ry + yn);
yn = unique(ry, ry + yn) - ry;
yid.clear();
for (int i = ; i < yn; i++) yid[ry[i]] = i;
xn--, yn--;
// for (int i = 0; i < xn; i++) cout << i << '~' << rx[i] << endl;
// for (int i = 0; i < yn; i++) cout << i << '-' << ry[i] << endl;
// cout << xn << ' ' << yn << endl;
memset(blx, , sizeof(blx));
for (int i = ; i < n; i++) fix(i);
// for (int i = 0; i < pn[0]; i++) cout << poly[0][i].first << ' ' << poly[0][i].second << endl;
for (int i = ; i < n; i++) fill(i);
// for (int j = 0; j < yn; j++) {
// for (int i = 0; i < xn; i++) printf("%d", blx[i][j]);
// puts("");
// }
} int main() {
// freopen("in", "r", stdin);
int T, n, x, y;
cin >> T;
while (T-- && cin >> L >> W) {
xn = yn = ;
L <<= , W <<= ;
rx[xn++] = L, ry[yn++] = W;
rx[xn++] = , ry[yn++] = ;
cin >> n;
for (int i = ; i < n; i++) {
cin >> pn[i];
for (int j = ; j < pn[i]; j++) {
scanf("%d%d", &poly[i][j].first, &poly[i][j].second);
poly[i][j].first <<= , poly[i][j].second <<= ;
rx[xn++] = poly[i][j].first, ry[yn++] = poly[i][j].second;
}
}
PRE(n);
cout << work(n) << endl;
}
return ;
} /*
10
12 8
3
8 5 1 11 1 11 5 7 5 7 4 9 4 9 2 5 2
4 0 3 3 3 3 4 0 4
4 1 4 2 4 2 6 1 6
10 10
3
4 1 1 5 1 5 5 1 5
4 5 3 9 3 9 8 5 8
4 0 5 1 5 1 4 0 4
10 10
1
10 1 1 1 4 0 4 0 5 5 5 5 8 9 8 9 3 5 3 5 1
10 10
1
10 1 1 5 1 5 3 9 3 9 8 5 8 5 5 0 5 0 4 1 4
1000000 1000000
1
8 1 1 1 999999 2 999999 2 999998 999998 999998 999998 999999 999999 999999 999999 1
1000000 1000000
1
8 1 1 1 999999 2 999999 2 2 999998 2 999998 999999 999999 999999 999999 1
1000000 1000000
3
6 1 1 1 999999 2 999999 2 2 999999 2 999999 1
4 3 2 3 1000000 4 1000000 4 2
4 5 2 5 999999 6 999999 6 2
1000000 1000000
4
6 1 1 1 999999 2 999999 2 2 999999 2 999999 1
4 3 2 3 1000000 4 1000000 4 2
4 5 2 5 999999 6 999999 6 2
4 6 999999 7 999999 7 1000000 6 1000000
1000000 1000000
5
6 1 1 1 999999 2 999999 2 2 999999 2 999999 1
4 3 2 3 1000000 4 1000000 4 2
4 5 2 5 999999 6 999999 6 2
4 6 999999 7 999999 7 1000000 6 1000000
4 999999 1 999999 2 1000000 2 1000000 1
1000000 1000000
3
6 1 1 1 999999 2 999999 2 2 999998 2 999998 1
4 999999 3 999999 4 1000000 4 1000000 3
4 999999 3 999999 2 999998 2 999998 3
*/
做题最蛋疼的事情不能理解透题目的意思。做这题的时候,自己不停的出数据坑自己,可是出到那么恶心了都找不到bug。以后还要更加注意细节!
——written by Lyon
poj 1689 && zoj 1422 3002 Rubbery (Geometry + BFS)的更多相关文章
- POJ 1562 && ZOJ 1709 Oil Deposits(简单DFS)
题目链接 题意 : 问一个m×n的矩形中,有多少个pocket,如果两块油田相连(上下左右或者对角连着也算),就算一个pocket . 思路 : 写好8个方向搜就可以了,每次找的时候可以先把那个点直接 ...
- POJ 1475 Pushing Boxes 搜索- 两重BFS
题目地址: http://poj.org/problem?id=1475 两重BFS就行了,第一重是搜索箱子,第二重搜索人能不能到达推箱子的地方. AC代码: #include <iostrea ...
- POJ 3076 / ZOJ 3122 Sudoku(DLX)
Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells ...
- poj 3100 (zoj 2818)||ZOJ 2829 ||ZOJ 1938 (poj 2249)
水题三题: 1.给你B和N,求个整数A使得A^n最接近B 2. 输出第N个能被3或者5整除的数 3.给你整数n和k,让你求组合数c(n,k) 1.poj 3100 (zoj 2818) Root of ...
- poj 1066 Treasure Hunt (Geometry + BFS)
1066 -- Treasure Hunt 题意是,在一个金字塔中有一个宝藏,金字塔里面有很多的墙,要穿过墙壁才能进入到宝藏所在的地方.可是因为某些原因,只能在两个墙壁的交点连线的中点穿过墙壁.问最少 ...
- ZOJ 1301 The New Villa (BFS + 状态压缩)
题意:黑先生新买了一栋别墅,可是里面的电灯线路的连接是很混乱的(每个房间的开关可能控制其他房间,房间数<=10),有一天晚上他回家时发现所有的灯(除了他出发的房间)都是关闭的,而他想回卧室去休息 ...
- [poj] 2396 [zoj] 1994 budget || 有源汇的上下界可行流
poj原题 zoj原题 //注意zoj最后一行不要多输出空行 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表不同赛区支出的矩阵.组委会曾经开会讨论过各类支出的总和,以及各赛区 ...
- poj 1475 || zoj 249 Pushing Boxes
http://poj.org/problem?id=1475 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=249 Pushin ...
- poj 2965 The Pilots Brothers' refrigerator枚举(bfs+位运算)
//题目:http://poj.org/problem?id=2965//题意:电冰箱有16个把手,每个把手两种状态(开‘-’或关‘+’),只有在所有把手都打开时,门才开,输入数据是个4*4的矩阵,因 ...
随机推荐
- Python实例 类和继承
class Base: def __init__(self): self.data = [] def add(self, x): self.data.a ...
- Uva116 Unidirectional TSP
https://odzkskevi.qnssl.com/292ca2c84ab5bd27a2a91d66827dd320?v=1508162936 https://vjudge.net/problem ...
- 洛谷P1029 最大公约数和最小公倍数问题 [2017年6月计划 数论02]
P1029 最大公约数和最小公倍数问题 题目描述 输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数 条件: 1 ...
- bzoj2212/3702 [Poi2011]Tree Rotations 线段树合并
Description Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some in ...
- linux源码安装
以安装xxx.tar.gz为例: 源码存放位置:/usr/local/src/ 安装路径:/usr/local/xxx/ 配置文件存放位置:/usr/local/xxx/etc/ 可执行文件存放位置: ...
- HR招聘_(五)_招聘方法论(电话邀约)
.主动候选人 这部分候选人通过职位广告直接投递,大多对公司意愿度高(排除少数海投候选人),所以电话中一般需要了解如下信息: 目前状态,在职还是离职: 离职原因以及真实诉求: 岗位职责和团队情况: 薪资 ...
- Java 1.8 Stream 用例测试
package stream; import model.Student; import org.junit.jupiter.api.Test; import java.util.*; import ...
- 重温 Webpack, Babel 和 React
开始之前 在书写文章之前,我假设大家已经有了 JavaScript,Node 包管理工具,Linux 终端操作 这些基本技能,接下来,我将一步一步指引大家从头搭建一个 React 项目 最终实现的效果 ...
- oralce管理命令
Emctl start agent TZ set to PRC Oracle Enterprise Manager 10g Database Control Release 10.2.0.1.0 Co ...
- BZOJ 4420二重镇题解
链接 思路借鉴了这个博客: 我们可以想到状压dp 用一个十进制数来表示状态,即第i位表示位置i处的物品等级 用f[i][j][k]表示第i天,仓库的物品等级为j,状态为k时的最大收益 但是状态数貌似很 ...