pro:给定一个N边形,然后给半径为R的圆,问是否可以放进去。  问题转化为多边形的最大内接圆半径。(N<50);

sol:乍一看,不就是二分+半平面交验证是否有核的板子题吗。 然而事情并没有那么简单。  因为我们的多边形可能是凹多边形,而前面的方法只对凸多边形有效。

学习了下模拟退火的算法,这个随机算法只在最小圆覆盖的时候写过。 这里再学一下,看起来更正宗一点的。  每次在当前点的附近(R)找是否能优化,而这个R慢慢变小,使得趋紧答案的趋势更精细。

判定点再多边形内:同样,不能用检验是否在每条边的左边来判定,因为不是凸多边形; 我们可以用射线法搞。

(rate和次数是抄的别人的,我自己也不会分析。 感觉这个取决于数据和人品吧

(随机要加srand来增加随机性。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
const double pi=acos(-1.0);
const double inf=0x7fffffff;
struct point {
double x,y;
point(){}
point(double xx,double yy):x(xx),y(yy){}
};
struct line{
point s,p;
line(){}
line(point xx,point yy):s(xx),p(yy){}
};
double getdis(point w,point v){
return sqrt((w.x-v.x)*(w.x-v.x)+(w.y-v.y)*(w.y-v.y));
}
point operator /(point a,double t){ return point(a.x/t,a.y/t);}
point operator *(point a,double t){ return point(t*a.x,t*a.y);}
point operator -(point w,point v){return point(w.x-v.x,w.y-v.y);}
point operator +(point w,point v){return point(w.x+v.x,w.y+v.y);}
double det(point w,point v){ return w.x*v.y-w.y*v.x;}
double dot(point w,point v){ return w.x*v.x+w.y*v.y;}
double ltoseg(point p,point a,point b){
point t=p-a;
if(dot(t,b-a)<=) return getdis(p,a);
else if(dot(p-b,a-b)<=) return getdis(p,b);
return fabs(det(t,b-a))/getdis(a,b);
}
point p[maxn],tp[maxn]; double dist[maxn]; int N; line L[maxn];
bool isinside(point a)
{
//算法描述:首先,对于多边形的水平边不做考虑,其次,
//对于多边形的顶点和射线相交的情况,如果该顶点时其所属的边上纵坐标较大的顶点,则计数,否则忽略该点,
//最后,对于Q在多边形上的情形,直接判断Q是否属于多边形。
int ncross=;
rep(i,,N-) {
point p1=p[i],p2=p[i+];
if(ltoseg(a,p[i],p[i+])==) return true; //在线段上
if(p1.y==p2.y) continue; //默认做水平x轴的线,所以水平线不考虑
if(a.y<min(p1.y,p2.y)) continue; //相离不考虑
if(a.y>max(p1.y,p2.y)) continue;
double t=det(a-p[i],a-p[i+]);
if((t>=&&p[i].y<a.y&&p[i+].y>=a.y)||(t<=&&p[i+].y<a.y&&p[i].y>=a.y)) ncross++;
}
return (ncross&);
}
double getmindis(point a)
{
double ans=inf;
rep(i,,N-) ans=min(ans,ltoseg(a,p[i],p[i+]));
return ans;
}
int main()
{
srand(unsigned(time(NULL)));
while(~scanf("%d",&N)&&N){
double X,Y,R; X=Y=;
rep(i,,N) {
scanf("%lf%lf",&p[i].x,&p[i].y);
X=max(X,p[i].x);
Y=max(Y,p[i].y);
}
p[]=p[N];
rep(i,,N-) L[i]=line(p[i],p[i+]-p[i]);
scanf("%lf",&R);
int maxt=min(N,);
rep(i,,maxt-){
tp[i]=(p[i]+p[i+])/;
dist[i]=;
}
double step=min(X,Y);
const int maxd=;
const double rate=0.55;
bool flag=;
const double EPS2=1e-;
while(step>EPS2&&!flag){
rep(i,,maxt-){
rep(j,,maxd-){
double d=rand()%/360.0**pi;
point next=tp[i];
next.x+=step*sin(d);
next.y+=step*cos(d);
if(!isinside(next)) continue;
double tdis=getmindis(next);
if(tdis+EPS2>dist[i]){
dist[i]=tdis; tp[i]=next;
}
if(tdis+EPS2>=R){
flag=; break;
}
}
}
step*=rate;
}
if(flag) puts("Yes");
else puts("No");
}
return ;
}

HDU - 3644:A Chocolate Manufacturer's Problem(模拟退火, 求多边形内最大圆半径)的更多相关文章

  1. [hdu3644 A Chocolate Manufacturer's Problem]模拟退火,简单多边形内最大圆

    题意:判断简单多边形内是否可以放一个半径为R的圆 思路:如果这个多边形是正多边形,令r(x,y)为圆心在(x,y)处多边形内最大圆的半径,不难发现,f(x,y)越靠近正多边形的中心,r越大,所以可以利 ...

  2. hdu 1115:Lifting the Stone(计算几何,求多边形重心。 过年好!)

    Lifting the Stone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  3. HDU - 2036 改革春风吹满地 叉乘法求多边形面积

    改革春风吹满地 “ 改革春风吹满地, 不会AC没关系; 实在不行回老家, 还有一亩三分地. 谢谢!(乐队奏乐)” 话说部分学生心态极好,每天就知道游戏,这次考试如此简单的题目,也是云里雾里,而且,还竟 ...

  4. hdu 4972 A simple dynamic programming problem(高效)

    pid=4972" target="_blank" style="">题目链接:hdu 4972 A simple dynamic progra ...

  5. HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  6. hdu 2865 Polya计数+(矩阵 or 找规律 求C)

    Birthday Toy Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  7. 实验12:Problem F: 求平均年龄

    Home Web Board ProblemSet Standing Status Statistics   Problem F: 求平均年龄 Problem F: 求平均年龄 Time Limit: ...

  8. (hdu step 7.1.3)Lifting the Stone(求凸多边形的重心)

    题目: Lifting the Stone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...

  9. Problem J: 求个最大值

    Problem J: 求个最大值 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 871  Solved: 663[Submit][Status][Web ...

随机推荐

  1. Oracle Spatial分区应用研究之四:不同分区粒度+全局空间索引效率对比

    1.实验目的 在实验之前先回答这样一个问题——对同一份数据使用不同的分区粒度,但均创建全局空间索引,问:它们的全局空间索引一致吗? 怎样算是一致的呢?R-TREE的树结构一致算一致吗?空间索引条目数及 ...

  2. pvs显示unknown device

    一 .不要unknown的那块pv盘的解决办法 [root@gezi ~]# pvs WARNING: Device for PV D1LLfT-3Hle-NbrP-5165-Q6WR-2UWF-2x ...

  3. [转帖]Stack Overflow上188万浏览量的提问:Java 到底是值传递还是引用传递?

    Stack Overflow上188万浏览量的提问:Java 到底是值传递还是引用传递? http://www.itpub.net/2019/12/03/4567/   在逛 Stack Overfl ...

  4. 嵌入式02 STM32 实验11 NVIC和中断总结

    一.基础知识 1.cortex-m3支持256个中断,其中包含了16个内核中断,240个外部中断 2.STM32只有84个中断,包括16个内核中断和68个可屏蔽中断 3.STM32F103上只有60个 ...

  5. c++11多线程记录3: 数据争用和Mutex的使用

    https://www.youtube.com/watch?v=3ZxZPeXPaM4 学习视频 数据争用 简单来说就是存在多个线程同时对某个共同的对象进行读写(至少有一个线程在做写操作),造成读取这 ...

  6. python学习-32 zip函数

    zip 拉链方法 例如:1. ')))) 运行结果: [(')] Process finished with exit code 0 2. a = {'name':'abc','age':18,'ad ...

  7. STM32学习笔记 —— 1.1 什么是寄存器(概念分析)

    问题引入: 用一句话回答以下问题: 什么是寄存器? 什么是寄存器映射? 什么是存储器映射? (本章重点在 1.1.3 和 1.1.4) 1.1 STM32芯片实物图 (图) 学会看丝印图 芯片型号.内 ...

  8. UI单据按钮点击事件校验

    一.按钮点击前事务处理<BeforeEventProcess> public override void BeforeEventProcess(IPart part, string eve ...

  9. Unity - 简单实现音频管理系统

    简单实现Unity音频管理脚本,便于长短音频的播放控制和音量控制等,核心方法为对象池的应用. 项目地址:AudioPlay - SouthBegonia 包含方法: 持有所有 AudioSource ...

  10. 论文笔记 : NCF( Neural Collaborative Filtering)

    ABSTRACT 主要点为用MLP来替换传统CF算法中的内积操作来表示用户和物品之间的交互关系. INTRODUCTION NeuCF设计了一个基于神经网络结构的CF模型.文章使用的数据为隐式数据,想 ...