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. Dijkstra,floyd,spfa三种最短路的区别和使用

    这里不列举三种算法的实现细节,只是简单描述下思想,分析下异同 一 Dijkstra Dijkstra算法可以解决无负权图的最短路径问题,只能应付单源起点的情况,算法要求两个集合,开始所有点在第二个集合 ...

  2. Android学习笔记之mainfest文件中android属性

    android:allowTaskReparenting 是否允许activity更换从属的任务,比如从短信息任务 切换到浏览器任务. -------------------------------- ...

  3. DirectX11笔记(十二)--Direct3D渲染8--EFFECTS

    原文:DirectX11笔记(十二)--Direct3D渲染8--EFFECTS 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010333737 ...

  4. python ndarray相关操作:拼接

  5. ubuntu上制作应用程序的快捷图标启动

    最近在研究Go语言,对比了几种流行的IDE,发现GoLand是使用体验最好的,没有之一.这也印证了网友们常说的那句话“JetBrain出品,必属精品”. 在ubuntu环境下使用GoLand,直接到J ...

  6. bnd.bnd属性文件格式

    1.Header以大写字母开头 Bundle-Name: StoreAdminProductsTool 2.Instruction以-和小写字母开头 -sources: true 3. Macro形式 ...

  7. GNN 相关资料记录;GCN 与 graph embedding 相关调研;社区发现算法相关;异构信息网络相关;

    最近做了一些和gnn相关的工作,经常听到GCN 和 embedding 相关技术,感觉很是困惑,所以写下此博客,对相关知识进行索引和记录: 参考链接: https://www.toutiao.com/ ...

  8. hdu3879 最大权闭合图

    若a,b 2点能够相连,那么可以得到ci的价值,也就是说a,b是得到c的前提条件,对于每一个点,又有耗费. 对于本题,先求出最多能够得到的利益有多少,最小割=未被 选的用户的收益之和 + 被选择的站点 ...

  9. springmvc restful风格操作

    ssm框架 controller: package com.sgcc.controller; import java.util.ArrayList; import java.util.List; im ...

  10. jdbc框架-dbutils的简单使用

    jdbc框架-dbutils的简单使用 dbutils:是apache组织的一个工具类,jdbc的框架,更方便我们使用 使用步骤: 1.导入jar包(commons-dbutils-1.4.jar) ...