博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1584 A Round Peg in a Ground Hole
阅读量:5746 次
发布时间:2019-06-18

本文共 2672 字,大约阅读时间需要 8 分钟。

POJ_1584

    这个题目思路是比较直接的,首先去判断这个多边形是否为凹多边形,如果不是凹多边形,就去判断圆是否在多边形内。

    在判断多边形是否为凹多边形时,可以将相邻的两个线段做叉积,从而判断在沿四边形走时是否只向左或者只向右转,从而说明这个多边形是否为凹多边形。从discuss里面看到说有的数据相邻的两个线段是共线的,要注意一下这样的情况。

    在判断圆是否在多边形内时,可以分两步,第一步判断圆心是否在多边形内,第二步判断圆和多边形是否“相割”。

    判断圆心是否在多边形内时,可以先规定好多边形的正方向,然后看这个点是否在所有线段向量的同一侧。

    判断圆和多边形是否“相割”时,可以先判断是否有多边形的顶点在圆的内部,如果存在这样的点,那么圆和多边形肯定是“相割”的。做完上一步判断后,对任意圆心到该线段的距离小于半径的线段还剩两种情况,要么和圆“相割”,要么在圆外,但线段的两个端点都是在圆外的,所以我们可以先找到这个线段的法向量,然后去判断线段的两个端点是否分布在以圆心为起点且与法向量同向的向量的异侧,如果分布在异侧,就可以说明这个线段是和圆“相割”的。

    不过,上面所说的判断圆和多边形是否“相割”的方法是针对任意一个简单多边形的,但由于这个题目后面就一定是非凹多边形了,所以直接判断圆心到每条线段的距离是否小于R即可。点到线段的距离可以用有向面积的绝对值除以线段的长度得到。

#include
#include
#define MAXD 160 #define zero 1e-8 int N; double R, X, Y, x[MAXD], y[MAXD]; void init() {
int i, j, k; scanf("%lf%lf%lf", &R, &X, &Y); for(i = 0; i < N; i ++) scanf("%lf%lf", &x[i], &y[i]); x[N] = x[0], y[N] = y[0]; } double fabs(double x) {
return x < 0 ? -x : x; } int dcmp(double x) {
if(fabs(x) < zero) return 0; if(x < 0) return -1; return 1; } double det(double x1, double y1, double x2, double y2) {
return x1 * y2 - x2 * y1; } int check1() {
int i, j, k, st = 0; for(i = 1; i < N; i ++) {
k = dcmp(det(x[i] - x[i - 1], y[i] - y[i - 1], x[i + 1] - x[i], y[i + 1] - y[i])); if(!st) st = k; if(k && st != k) return 0; } return 1; } int inpolygon() {
int i, j, k, st; st = dcmp(det(x[1] - x[0], y[1] - y[0], X - x[0], Y - y[0])); if(st == 0) return 0; for(i = 1; i < N; i ++) {
k = dcmp(det(x[i + 1] - x[i], y[i + 1] - y[i], X - x[i], Y - y[i])); if(k != st) return 0; } return 1; } int check2() {
int i, j, k; double t, t1, t2, dx, dy; if(!inpolygon()) return 0; for(i = 0; i < N; i ++) if(dcmp((x[i] - X) * (x[i] - X) + (y[i] - Y) * (y[i] - Y) - R * R) == -1) return 0; for(i = 0; i < N; i ++) {
t = det(x[i] - X, y[i] - Y, x[i + 1] - X, y[i + 1] - Y); t = t * t / ((x[i + 1] - x[i]) * (x[i + 1] - x[i]) + (y[i + 1] - y[i]) * (y[i + 1] - y[i])); if(dcmp(t - R * R) == -1) {
if(dcmp(y[i] - y[i + 1]) == 0) dx = 0, dy = 1; else dx = 1, dy = (x[i] - x[i + 1]) / (y[i + 1] - y[i]); } t1 = dcmp(det(dx, dy, x[i] - X, y[i] - Y)); t2 = dcmp(det(dx, dy, x[i + 1] - X, y[i + 1] - Y)); if(t1 * t2 < 0) return 0; } return 1; } void solve() {
int i, j, k; if(!check1()) printf("HOLE IS ILL-FORMED\n"); else {
if(check2()) printf("PEG WILL FIT\n"); else printf("PEG WILL NOT FIT\n"); } } int main() {
for(;;) {
scanf("%d", &N); if(N < 3) break; init(); solve(); } return 0; }

转载地址:http://obxzx.baihongyu.com/

你可能感兴趣的文章
es6数组新方法
查看>>
leetcode:Factorial Trailing Zeroes
查看>>
【iOS开发】如何在程序出错崩溃时快速定位到具体出错代码行
查看>>
甲知道两数之和,⼄知道两数之积,求两数字
查看>>
谷歌获奖生产属于自己的手机
查看>>
[ZJOI2015]诸神眷顾的幻想乡
查看>>
Elementary Methods in Number Theory Exercise 1.5.13
查看>>
文章评论:级数中达朗贝尔判别法和柯西判别法之间的关系研究 By 彭军
查看>>
陶哲轩实分析 命题 7.2.14 (极限算律) 证明
查看>>
Thread和Runnable
查看>>
JavaScript禁用页面内容选中和复制操作
查看>>
浅析Objective-C字面量
查看>>
dojo 与j Query一些常用API上的命名和参数的对比
查看>>
Dojo DOM 函数[转]
查看>>
JavaScript 基础,登录前端验证
查看>>
xmlrpc
查看>>
明天我爱谁
查看>>
图片缩略图插件 jqthumb.js
查看>>
python 找到列表中满足某些条件的元素
查看>>
小小练习:测试获取用户信息接口
查看>>