http://acm.hdu.edu.cn/showproblem.php?pid=1221

1
14 92 31 95 13 96 3

这题只需要判断圆和矩形是否相交,然后在里面是不算相交的。

那么就有好几种情况了。

1、整个矩形在圆形里,NO,(我的做法是所有点到圆心距离小于半径)

2、整个圆在矩形里,NO,一个圆选出5个点,圆心,和最上下左右,如果这些点都在,则不行。我的做法直接PointInPolygon。

3、否则,只要有公共点,就直接YES。然后,如果圆那5个点有一个在矩形,或者矩形的4个点到圆心的距离小于半径,即可。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
#define MY "H:/CodeBlocks/project/CompareTwoFile/DataMy.txt", "w", stdout
#define ANS "H:/CodeBlocks/project/CompareTwoFile/DataAns.txt", "w", stdout
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const double eps = 1e-;
bool same(double x, double y) {
return fabs(x - y) < eps;
}
struct coor {
double x,y;
coor() {}
coor(double xx,double yy):x(xx),y(yy) {}
double operator ^(coor rhs) const { //计算叉积(向量积),返回数值即可
return x*rhs.y - y*rhs.x;
}
coor operator -(coor rhs) const { //坐标相减,a-b得到向量ba,返回一个向量(坐标形式)
return coor(x-rhs.x,y-rhs.y);
}
double operator *(coor rhs) const { //数量积,返回数值即可
return x*rhs.x + y*rhs.y;
}
bool operator ==(coor rhs) const {
return same(x,rhs.x)&&same(y,rhs.y); //same的定义其实就是和eps比较
}
} a[], cir[];
double dis(coor a, coor b) {
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
} bool OnSegment (coor a,coor b,coor cmp) { //判断点cmp是否在线段ab上
double min_x = min(a.x,b.x), min_y = min(a.y,b.y);
double max_x = max(a.x,b.x), max_y = max(a.y,b.y);
if (cmp.x>=min_x && cmp.x<=max_x && cmp.y>=min_y && cmp.y<=max_y) return true;
else return false;
} int PointInPolygon (coor p[],int n,coor cmp) {
int cnt = ; //记录单侧有多少个交点,这里的p[],必须有顺序
for (int i=; i<=n; ++i) {
int t = (i+)>n ? :(i+); //下标为1要这样MOD
coor p1=p[i],p2=p[t];
//printf ("%lf %lf %lf %lf***\n",p1.x,p1.y,p2.x,p2.y);
if (OnSegment(p1,p2,cmp)) {
coor t1 = p1-cmp,t2 = p2-cmp; //同时要叉积等于0,这是在线段上的前提
if ((t1^t2)==) return ;// 2表明在多边形上,可以适当省略
}
if (cmp.y >= max(p1.y,p2.y)) continue;//交点在延长线上和在凸顶点上的都不要
if (cmp.y < min(p1.y,p2.y)) continue;//交点在凹顶点上就要,这里没取等
if (same(p1.y,p2.y)) continue; //与cmp.y是平行的
double x = (cmp.y-p1.y)*(p1.x-p2.x)/(p1.y-p2.y) + p1.x; //求交点 p1.y != p2.y不会除0
if (x>cmp.x) cnt++;//只统计一侧的交点
}
return cnt&;//0表明点在多边形外,1表明点在多边形内
} void work() {
double x, y, R;
scanf("%lf%lf%lf", &x, &y, &R);
double xx1, xx2, yy1, yy2;
scanf("%lf%lf%lf%lf", &xx1, &yy1, &xx2, &yy2);
int lena = ;
a[++lena] = coor(xx1, yy1);
a[++lena] = coor(xx1, yy2);
a[++lena] = coor(xx2, yy2);
a[++lena] = coor(xx2, yy1); int lencir = ;
cir[++lencir] = coor(x + R, y);
cir[++lencir] = coor(x, y + R);
cir[++lencir] = coor(x - R, y);
cir[++lencir] = coor(x, y - R);
cir[++lencir] = coor(x, y);
int up = ;
for (int i = ; i <= lencir; ++i) {
if (PointInPolygon(a, , cir[i])) {
up++;
}
if (PointInPolygon(a, , cir[i]) == && i != lencir) {
printf("YES\n");
return;
}
}
if (up == lencir) {
printf("NO\n");
return;
}
up = ;
for (int i = ; i <= lena; ++i) {
double tdis = dis(a[i], coor(x, y));
if (same(tdis, R)) {
printf("YES\n");
return;
}
if (tdis < R) up++;
}
if (up == lena) {
printf("NO\n");
return;
} for (int i = ; i <= lena; ++i) {
double tdis = dis(a[i], coor(x, y));
if (same(tdis, R) || tdis < R) {
printf("YES\n");
return;
}
} for (int i = ; i <= lencir; ++i) {
if (PointInPolygon(a, , cir[i])) {
printf("YES\n");
return;
}
}
printf("NO\n");
// cout << dis(coor(5,5), coor(7, 7)) << endl;
return;
}
int main() {
#ifdef local
freopen("data.txt","r",stdin);
freopen(MY);
#endif
int t;
scanf("%d", &t);
while (t--) {
work();
}
return ;
}

开始的时候,判断有一个点在就行的时候,(就是相切的时候),把圆心也算进去了,坑了半天。

https://www.desmos.com/calculator  分享个画图工具,矩形的话,就直接是x>=10 x <= 99这样画

HDU 1221 Rectangle and Circle 考虑很多情况,good题的更多相关文章

  1. HDU 1221 Rectangle and Circle(判断圆和矩形是不是相交)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1221 Rectangle and Circle Time Limit: 2000/1000 MS (J ...

  2. libgdx学习记录25——Rectangle与Circle是否重叠

    Rect与Circle重叠有三种情况: 1. Rect至少有一个角在Circle里面 2. Circle与Rect的左边或右边相交,或者Circle在Rect内 3. Circle与Rect的顶边或底 ...

  3. Leaflet:Path、Polyline、Polygon、Rectangle、Circle、CircleMarker

    下边介绍Vector Layer Path(Layer) Path是其他Vector Layer的父类,比如Polyline.Polygon.Rectangle.Circle.CircleMarker ...

  4. hdu 5288||2015多校联合第一场1001题

    pid=5288">http://acm.hdu.edu.cn/showproblem.php?pid=5288 Problem Description OO has got a ar ...

  5. hdu 5343 MZL's Circle Zhou SAM

    MZL's Circle Zhou 题意:给定两个长度不超过a,b(1 <= |a|,|b| <= 90000),x为a的连续子串,b为y的连续子串(x和y均可以是空串):问x+y形成的不 ...

  6. 判断圆和矩形是否相交C - Rectangle and Circle

    Description Given a rectangle and a circle in the coordinate system(two edges of the rectangle are p ...

  7. HDU 5343 MZL's Circle Zhou

    MZL's Circle Zhou Time Limit: 1000ms Memory Limit: 131072KB This problem will be judged on HDU. Orig ...

  8. opencv —— line、ellipse、rectangle、circle、fillPoly、putText 基本图形的绘制

    绘制线段:line 函数 void line(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, ...

  9. HDU 5343 MZL's Circle Zhou 后缀自动机+DP

    MZL's Circle Zhou Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

随机推荐

  1. 安卓开发中使用ZXing生成解析二维码

    编码示例 package com.wolf_pan.qrcodesample; import android.graphics.Bitmap; import android.graphics.Colo ...

  2. C++ HOJ 火车进站

    [问题描写叙述] 给定一个正整数N代表火车数量.0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号. 要求以字典序排序输出火车出站的序列号. 输入:   有多组 ...

  3. 附录: mysql show processlist中的State的意义

    附录: mysql show processlist中的State的意义 Checking table 正在检查数据表(这是自动的). Closing tables 正在将表中修改的数据刷新到磁盘中, ...

  4. devm_regmap_init_i2c【转】

    本文转载自:http://blog.csdn.net/u011975319/article/details/52128845 本文有此处转载http://blog.csdn.net/luckywang ...

  5. 计算一个大数n的阶乘的位数宽度(十进制)(log i累加法 )

    输入: 每行输入1个正整数n, (0<n<1000 000) 输出: 对于每个n,输出n!的(十进制)位数. 分析: 这道题采用蛮力法.根据定义,直接求解! 所谓n!的十进制位数,就是 l ...

  6. MYSQL进阶学习笔记五:MySQL函数的创建!(视频序号:进阶_13)

    知识点六:MySQL函数的创建(13) 内置函数: 自定义函数: 首先查看是否已经开启了创建函数的功能: SHOW VARIABLES LIKE ‘%fun%’; 如果变量的值是OFF,那么需要开启 ...

  7. set built-in function

    集合类型 集合对象是一组无序排列的可哈希的值,集合可以作为字典的键.因为集合是无序的,不可以为集合创建索引或执行切片操作,也没有键可以用来获取元素的值. 集合有两种不同的类型,可变集合和不可变集合.可 ...

  8. 怎么往mac中finder个人收藏里添加文件夹

    1.打开Finder,点击左上角finder偏好设置 2.选择边栏 3.如果侧栏中没有的文件夹,直接长按文件夹直接拖入.

  9. SPOJ:OR(位运算&数学期望)

    Given an array of N integers A1, A2, A3…AN. If you randomly choose two indexes i ,j such that 1 ≤ i ...

  10. bzoj3270博物馆——期望概率DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3270 设计一个状态表示两个人分别在两个点的状态,带个标号num[i][j]: 据此得到状态之 ...