ZOJ :: Problems :: Show Problem

1689 -- 3002 Rubbery

  这题是从校内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)的更多相关文章

  1. POJ 1562 && ZOJ 1709 Oil Deposits(简单DFS)

    题目链接 题意 : 问一个m×n的矩形中,有多少个pocket,如果两块油田相连(上下左右或者对角连着也算),就算一个pocket . 思路 : 写好8个方向搜就可以了,每次找的时候可以先把那个点直接 ...

  2. POJ 1475 Pushing Boxes 搜索- 两重BFS

    题目地址: http://poj.org/problem?id=1475 两重BFS就行了,第一重是搜索箱子,第二重搜索人能不能到达推箱子的地方. AC代码: #include <iostrea ...

  3. POJ 3076 / ZOJ 3122 Sudoku(DLX)

    Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells ...

  4. 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 ...

  5. poj 1066 Treasure Hunt (Geometry + BFS)

    1066 -- Treasure Hunt 题意是,在一个金字塔中有一个宝藏,金字塔里面有很多的墙,要穿过墙壁才能进入到宝藏所在的地方.可是因为某些原因,只能在两个墙壁的交点连线的中点穿过墙壁.问最少 ...

  6. ZOJ 1301 The New Villa (BFS + 状态压缩)

    题意:黑先生新买了一栋别墅,可是里面的电灯线路的连接是很混乱的(每个房间的开关可能控制其他房间,房间数<=10),有一天晚上他回家时发现所有的灯(除了他出发的房间)都是关闭的,而他想回卧室去休息 ...

  7. [poj] 2396 [zoj] 1994 budget || 有源汇的上下界可行流

    poj原题 zoj原题 //注意zoj最后一行不要多输出空行 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表不同赛区支出的矩阵.组委会曾经开会讨论过各类支出的总和,以及各赛区 ...

  8. poj 1475 || zoj 249 Pushing Boxes

    http://poj.org/problem?id=1475 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=249 Pushin ...

  9. poj 2965 The Pilots Brothers' refrigerator枚举(bfs+位运算)

    //题目:http://poj.org/problem?id=2965//题意:电冰箱有16个把手,每个把手两种状态(开‘-’或关‘+’),只有在所有把手都打开时,门才开,输入数据是个4*4的矩阵,因 ...

随机推荐

  1. Python实例 类和继承

    class Base:     def __init__(self):         self.data = []     def add(self, x):         self.data.a ...

  2. Uva116 Unidirectional TSP

    https://odzkskevi.qnssl.com/292ca2c84ab5bd27a2a91d66827dd320?v=1508162936 https://vjudge.net/problem ...

  3. 洛谷P1029 最大公约数和最小公倍数问题 [2017年6月计划 数论02]

    P1029 最大公约数和最小公倍数问题 题目描述 输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数 条件: 1 ...

  4. bzoj2212/3702 [Poi2011]Tree Rotations 线段树合并

    Description Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some in ...

  5. linux源码安装

    以安装xxx.tar.gz为例: 源码存放位置:/usr/local/src/ 安装路径:/usr/local/xxx/ 配置文件存放位置:/usr/local/xxx/etc/ 可执行文件存放位置: ...

  6. HR招聘_(五)_招聘方法论(电话邀约)

    .主动候选人 这部分候选人通过职位广告直接投递,大多对公司意愿度高(排除少数海投候选人),所以电话中一般需要了解如下信息: 目前状态,在职还是离职: 离职原因以及真实诉求: 岗位职责和团队情况: 薪资 ...

  7. Java 1.8 Stream 用例测试

    package stream; import model.Student; import org.junit.jupiter.api.Test; import java.util.*; import ...

  8. 重温 Webpack, Babel 和 React

    开始之前 在书写文章之前,我假设大家已经有了 JavaScript,Node 包管理工具,Linux 终端操作 这些基本技能,接下来,我将一步一步指引大家从头搭建一个 React 项目 最终实现的效果 ...

  9. oralce管理命令

    Emctl start agent TZ set to PRC Oracle Enterprise Manager 10g Database Control Release 10.2.0.1.0 Co ...

  10. BZOJ 4420二重镇题解

    链接 思路借鉴了这个博客: 我们可以想到状压dp 用一个十进制数来表示状态,即第i位表示位置i处的物品等级 用f[i][j][k]表示第i天,仓库的物品等级为j,状态为k时的最大收益 但是状态数貌似很 ...