Feng Shui POJ - 3384

题意:n个顶点的凸包,放入2个半径为r的圆,可以重叠,要求面积最大,输出2个圆的圆心坐标(保留4位小数)

思路:找出圆心的可行域(内推r,求半平面交),再求核内最远的2个点坐标

#include<cstdio>
#include<vector>
#include<cmath>
#include<string>
#include<string.h>
#include<iostream>
#include<algorithm>
#define PI acos(-1.0)
#define pb push_back
#define F first
#define S second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e3+3;
const int MOD=1e9+7;
const double eps=1e-20;
template <class T>
bool sf(T &ret){ //Faster Inputchar c; int sgn; T bit=0.1;if(c=getchar(),c==EOF) return 0;while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();sgn=(c=='-')?-1:1;ret=(c=='-')?0:(c-'0');while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');if(c==' '||c=='\n'){ ret*=sgn; return 1; }while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;ret*=sgn;return 1;
}
int sign(double x) {  //三态函数,减少精度问题return abs(x) < eps ? 0 : x < 0 ? -1 : 1;
}
struct Point { //点的定义double x, y;Point(double x=0.0, double y=0.0) : x(x), y(y) {}Point operator + (const Point &rhs) const {  //向量加法return Point(x + rhs.x, y + rhs.y);}Point operator - (const Point &rhs) const {  //向量减法return Point(x - rhs.x, y - rhs.y);}Point operator * (double p) const {  //向量乘以标量return Point(x * p, y * p);}Point operator / (double p) const {  //向量除以标量return Point(x / p, y / p);}bool operator < (const Point &rhs) const {  //点的坐标排序return x < rhs.x || (x == rhs.x && y < rhs.y);}bool operator == (const Point &rhs) const {  //判断同一个点return sign(x - rhs.x) == 0 && sign(y - rhs.y) == 0;}};
typedef Point Vector;
double polar_angle(Vector A) {  //向量极角return atan2(A.y, A.x);
}struct Line {  //有向直线的定义,左边就是对应的半平面Point p,s;  //直线上任意一点Vector v;  //方向向量double ang;  //极角,即从x正方向旋转到向量v所需的角(弧度)Line() {}Line(Point p, Point s, Vector v) : p(p), s(s) ,v(v) {ang = polar_angle(v);}bool operator < (const Line &rhs) const {return ang < rhs.ang;}Point point(double a) {return p + v * a;}
};
double cross(Vector A, Vector B) {  //向量叉积,两向量组成的三角形的有向面积的两倍,可判断两向量的方向return A.x * B.y - A.y * B.x;
}
bool point_on_left(Point p, Line L) {  //判断点在直线左侧return cross(L.v, p-L.p) > 0;
}
Point line_line_inter(Point p, Vector V, Point q, Vector W) {  //两直线交点,参数方程Vector U = p - q;double t = cross(W, U) / cross(V, W);  //两直线有唯一交点的前提:cross(V, W)非0return p + V * t;
}
Point p[N];
Line Q[N];
typedef vector<Point> polygon;
typedef vector<Point> polygon;
bool HPIcmp(Line a,Line b){if(fabs(a.ang - b.ang) > eps)return a.ang < b.ang; //斜率排序//斜率相同return sign(cross((a.p - b.p),(b.s - b.p))) < 0;
}
polygon half_plane_inter(vector<Line> line){int n=(int)line.size();int tot=n;sort(line.begin(),line.end(),HPIcmp);polygon ans;tot = 1;for(int i = 1;i < n;i++)if(fabs(line[i].ang - line[i-1].ang) > eps) //去掉斜率重复的line[tot++] = line[i];int head = 0, tail = 1;Q[0] = line[0];Q[1] = line[1];for(int i = 2; i < tot; i++){ //如果双端队列底端或顶端两个半平面的交点在当前半平面之外,则删除if(fabs(cross((Q[tail].s-Q[tail].p),(Q[tail-1].s-Q[tail-1].p))) <eps ||fabs(cross((Q[head].s-Q[head].p),(Q[head+1].s-Q[head+1].p))) <eps)return ans;while(head < tail && sign(cross(line_line_inter(Q[tail].p,Q[tail].v,Q[tail-1].p,Q[tail-1].v)-line[i].p,line[i].s-line[i].p))>0)tail--;while(head < tail && sign(cross(line_line_inter(Q[head].p,Q[head].v,Q[head+1].p,Q[head+1].v)-line[i].p,line[i].s-line[i].p))>0)head++;Q[++tail] = line[i];}while(head < tail && sign(cross(line_line_inter(Q[tail].p,Q[tail].v,Q[tail-1].p,Q[tail-1].v)-Q[head].p,Q[head].s-Q[head].p))>0)tail--;if(tail <= head + 1) return ans;//保存点到ansfor(int i = head; i < tail; i++)ans.pb(line_line_inter(Q[i].p,Q[i].v,Q[i+1].p,Q[i+1].v));if(head < tail - 1)ans.pb(line_line_inter(Q[head].p,Q[head].v,Q[tail].p,Q[tail].v));return ans;
}
double dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;
}
double length(Vector A){return sqrt(dot(A,A));
}
Vector normal(Vector A) {  //向量的单位法向量,确保A不是零向量double len = length(A);return Vector(-A.y/len, A.x/len);
}
int ks;
Vector V1[N];
double dis(Point a,Point b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int main(void){int T,n;double r;while((scanf("%d%lf",&n,&r))==2){for(int i=0;i<n;i++)    scanf("%lf%lf",&p[i].x,&p[i].y);reverse(p,p+n);vector<Line> L;for(int i=0;i<n;i++){V1[i]=normal(p[(i+1)%n]-p[i]);Line t (p[i]+V1[i]*r,p[(i+1)%n]+V1[i]*r,p[(i+1)%n]-p[i]); /// 只能数放后面乘,重载设定L.pb(t);}vector<Point> res=half_plane_inter(L);
//        cout <<"sz="<<res.size() << endl;
//        for(auto t : res)   cout <<t.x<< " "<<t.y<<endl;double mx=0.0;pair<Point,Point> ans;n=(int)res.size();for(int i=0;i<n;i++){for(int j=i+1;j<n;j++){if(sign(dis(res[i],res[j])-mx)>=0){ //>= 如果2点重合.... 注意胰一下mx=dis(res[i],res[j]);ans={res[i],res[j]};}}}printf("%.4f %.4f %.4f %.4f\n",ans.F.x,ans.F.y,ans.S.x,ans.S.y);}return 0;
}

Feng Shui POJ - 3384 [半平面交]相关推荐

  1. Feng Shui POJ - 3384

    题目链接:https://cn.vjudge.net/problem/POJ-3384 #include<cstdio> #include<cstring> #include& ...

  2. POJ - 3384 Feng Shui(半平面交)

    链接 Feng Shui 题意 将两个半径为 rrr 的圆放入一个多边形中,两个圆占据最大面积时圆心坐标是多少: 思路 在多边形中放圆,最大圆的圆心一定在多边形内核中: 将多边形的每条边都内推 rrr ...

  3. POJ 3384 Feng Shui(半平面交)

    题意 : 给你一个凸多边形,让你在其中找两个圆,使得圆的覆盖面积最大. 这个题目和 poj 3525 有点类似,那个题目是一个圆,想到两者的联系,可以发现两个圆覆盖面积最大就是重叠面积最小,怎样使得重 ...

  4. poj 3384 Feng Shui (Half Plane Intersection)

    3384 -- Feng Shui 构造半平面交,然后求凸包上最远点对. 这题的题意是给出一个凸多边形区域,要求在其中放置两个半径为r的圆(不能超出凸多边形区域),要求求出两个圆心,使得多边形中没有被 ...

  5. POJ 3384 Feng Shui

    坑爹的题,,就是先向内推进r,然后半平面交得出圆心范围. 然后旋转卡壳求最远点对 这道题首先样例给的就不对,不知道什么情况 然后一直WA,后来看了discuss,试了下这组数据: 4 1 0 0 0 ...

  6. CodeForces - Feng Shui(半平面交)

    题目链接:http://codeforces.com/gym/101650/attachments Time Limit: 2000MS Memory Limit: 65536K Descriptio ...

  7. [POJ3384]Feng Shui(半平面交+凸包)

    题目: 我是超链接 题意: 在一个凸多边形中放两个半径固定的圆,要求输出使覆盖面积最大的(可重叠)两个圆圆心 题解: Emmm...套路缩小凸多边形,形成的凸包是圆心可以在的位置,然后暴力找最远点! ...

  8. POJ 1474 Video Surveillance(半平面交)

    题意:半平面交求多边形内核(我明明及的我之前是会用kuangbin第一份版平面交的,现在怎么就不会用了呢,补第二份代码) 代码: #include<cstdio> #include< ...

  9. poj 1755 Triathlon (半平面交解一元二次不等式)(切割求半平面交)

    题目链接:哆啦A梦传送门 参考链接:https://blog.csdn.net/acm_cxlove/article/details/7883370 半平面交模板 题目:铁人三项,每个人在某一项中有确 ...

最新文章

  1. 史上最全的“大数据”学习资源
  2. Android 7.0 init.rc的一点改变
  3. matlab7.0调节视图,新手求救啊!!!matlab7.0在win7启动后命令窗口出现大段代码!...
  4. 发明个人计算机哪国人,电脑是哪国人发明的,发明的人是谁??
  5. python处理word文档保留格式_python 处理document文档 保留原样式
  6. Spyder打开报错解决办法
  7. 使用 Swagger UI 与 Swashbuckle 创建 RESTful Web API 帮助文件
  8. 实在小店在B2C平台具有一定的知名度
  9. ps6人脸识别液化工具在哪_PS上手指南 篇五:玩转人脸识别液化
  10. 什么是Android手机
  11. Vue上传文件 iview Upload UI 组件上传组件
  12. 教你解决M1芯片MAC安装PS2021卡在启动屏幕,完美解决PS21卡启动屏幕
  13. js清除cookie有时无法清除
  14. Java SE MyBatis框架(详解)
  15. 【JavaEE进阶系列 | 从小白到工程师】JavaWeb中的过滤器(Filter)和监听器(Listener)区别,看这一篇就够
  16. 通信电子电路(一)通电课程背景 以及选频网络概念
  17. Pandas基础教程
  18. 惠普战66系列拆机图文详解
  19. HP Smart连接异常缓慢,点击扫描闪退
  20. java 运行批处理文件_如何从Java应用程序运行批处理文件?

热门文章

  1. Frame skipped from debugging during step-in. VSCode调试无法定位其它库中代码的解决办法
  2. Raven2靶机练习
  3. 腾讯安全领御为张裕打造高端葡萄酒区块链溯源平台
  4. 记录:google map谷歌地图自定义叠加层overlay流程
  5. IntelliJ IDEA 下载安装及其破解
  6. Quartus Prime v18.1 standard-QuartusPrimeV18.1标准版安装过程
  7. 出走的门徒之四:丰元创投朱会灿:冒险的牧师
  8. 朱会灿:搜索引擎演变史 视频及PPT放出 - 讲堂活动 - 腾讯大讲堂
  9. redis5大数据结构
  10. ubuntu16.04登录界面输入用户名密码后又回到登录界面