题意:判断简单多边形内是否可以放一个半径为R的圆

思路:如果这个多边形是正多边形,令r(x,y)为圆心在(x,y)处多边形内最大圆的半径,不难发现,f(x,y)越靠近正多边形的中心,r越大,所以可以利用模拟退火法来逼近最优点。对于一般的多边形,由于可能存在多个这样的"局部最优点",所以可以选不同的点作为起点进行多若干次模拟退火即可。

模拟退火的过程:每次由原状态S生成一个新状态T,如果T比S优,那么接受这一次转移,否则以一定概率P接受这次转移,因为这样可能会跳过局部最优解而得到全局最优解。

PS:步长每次改变的系数一般设为0.8~0.9,eps不能设太高。

#pragma comment(linker, "/STACK:10240000")
#include <bits/stdc++.h>
using namespace std; #define X first
#define Y second
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a)) typedef long long ll;
typedef pair<int, int> pii; namespace Debug {
void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<" ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?:-;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
}
template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
/* -------------------------------------------------------------------------------- */ const double eps = 1e-4;/** 设置比较精度 **/
struct Real {
double x;
double get() { return x; }
int read() { return scanf("%lf", &x); }
Real(const double &x) { this->x = x; }
Real() {}
Real abs() { return x > ? x : -x; } Real operator + (const Real &that) const { return Real(x + that.x);}
Real operator - (const Real &that) const { return Real(x - that.x);}
Real operator * (const Real &that) const { return Real(x * that.x);}
Real operator / (const Real &that) const { return Real(x / that.x);}
Real operator - () const { return Real(-x); } Real operator += (const Real &that) { return Real(x += that.x); }
Real operator -= (const Real &that) { return Real(x -= that.x); }
Real operator *= (const Real &that) { return Real(x *= that.x); }
Real operator /= (const Real &that) { return Real(x /= that.x); } bool operator < (const Real &that) const { return x - that.x <= -eps; }
bool operator > (const Real &that) const { return x - that.x >= eps; }
bool operator == (const Real &that) const { return x - that.x > -eps && x - that.x < eps; }
bool operator <= (const Real &that) const { return x - that.x < eps; }
bool operator >= (const Real &that) const { return x - that.x > -eps; } friend ostream& operator << (ostream &out, const Real &val) {
out << val.x;
return out;
}
friend istream& operator >> (istream &in, Real &val) {
in >> val.x;
return in;
}
}; struct Point {
Real x, y;
int read() { return scanf("%lf%lf", &x.x, &y.x); }
Point(const Real &x, const Real &y) { this->x = x; this->y = y; }
Point() {}
Point operator + (const Point &that) const { return Point(this->x + that.x, this->y + that.y); }
Point operator - (const Point &that) const { return Point(this->x - that.x, this->y - that.y); }
Real operator * (const Point &that) const { return x * that.x + y * that.y; }
Point operator * (const Real &that) const { return Point(x * that, y * that); }
Point operator += (const Point &that) { return Point(this->x += that.x, this->y += that.y); }
Point operator -= (const Point &that) { return Point(this->x -= that.x, this->y -= that.y); }
Point operator *= (const Real &that) { return Point(x *= that, y *= that); } bool operator == (const Point &that) const { return x == that.x && y == that.y; } Real cross(const Point &that) const { return x * that.y - y * that.x; }
Real dist() { return sqrt((x * x + y * y).get()); }
};
typedef Point Vector; struct Segment {
Point a, b;
Segment(const Point &a, const Point &b) { this->a = a; this->b = b; }
Segment() {}
bool intersect(const Segment &that) const {
Point c = that.a, d = that.b;
Vector ab = b - a, cd = d - c, ac = c - a, ad = d - a, ca = a - c, cb = b - c;
return ab.cross(ac) * ab.cross(ad) < && cd.cross(ca) * cd.cross(cb) < ;
}
Point getLineIntersection(const Segment &that) const {
Vector u = a - that.a, v = b - a, w = that.b - that.a;
Real t = w.cross(u) / v.cross(w);
return a + v * t;
}
Real Distance(Point P) {
Point A = a, B = b;
if (A == B) return (P - A).dist();
Vector v1 = B - A, v2 = P - A, v3 = P - B;
if (v1 * v2 < ) return v2.dist();
if (v1 * v3 > ) return v3.dist();
return v1.cross(v2).abs() / v1.dist();
}
}; const int maxn = ;
double PI = acos(-1.0); Point p[maxn];
int n; Real getAngel(Point o, Point a, Point b) {
a -= o;
b -= o;
Real ans = acos((a * b / a.dist() / b.dist()).get());
return a.cross(b) <= ? ans : -ans;
} bool inPolygon(Point o) {
Real total = ;
for (int i = ; i < n; i ++) {
total += getAngel(o, p[i], p[(i + ) % n]);
}
return total.abs() > PI;
} Real getR(Point o) {
Real ans = 1e9;
for (int i = ; i < n; i ++) {
Segment seg(p[i], p[(i + ) % n]);
umin(ans, seg.Distance(o));
}
return ans;
} int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
while (cin >> n, n) {
p[].read();
Real maxx = p[].x, minx = p[].x, maxy = p[].y, miny = p[].y;
for (int i = ; i < n; i ++) {
p[i].read();
umax(maxx, p[i].x);
umin(minx, p[i].x);
umax(maxy, p[i].y);
umin(miny, p[i].y);
}
Real R;
R.read();
Point a(minx, miny), b(maxx, maxy);
bool ok = false;
for (int i = ; !ok && i < n; i ++) {
Real deta = (b - a).dist() / ;
Point O = (p[i] + p[(i + ) % n]) * 0.5;
int cnt = ;
while (!ok && deta > && cnt < ) {
for (int j = ; ; j ++) {
double randnum = rand();
Point newp(O.x + deta * sin(randnum), O.y + deta * cos(randnum));
if (!inPolygon(newp)) continue;
Real buf = getR(newp);
if (buf > getR(O) || j > ) { /** 这里考虑了概率因素 **/
if (buf >= R) ok = true;
O = newp;
break;
}
}
deta *= 0.8;
cnt ++;
}
}
puts(ok? "Yes" : "No");
} }

[hdu3644 A Chocolate Manufacturer's Problem]模拟退火,简单多边形内最大圆的更多相关文章

  1. HDU - 3644:A Chocolate Manufacturer's Problem(模拟退火, 求多边形内最大圆半径)

    pro:给定一个N边形,然后给半径为R的圆,问是否可以放进去.  问题转化为多边形的最大内接圆半径.(N<50): sol:乍一看,不就是二分+半平面交验证是否有核的板子题吗. 然而事情并没有那 ...

  2. Codeforces Beta Round #2 C. Commentator problem 模拟退火

    C. Commentator problem 题目连接: http://www.codeforces.com/contest/2/problem/C Description The Olympic G ...

  3. How Cocoa Beans Grow And Are Harvested Into Chocolate

    What is Cocoa Beans Do you like chocolate? Most people do. The smooth, brown candy is deliciously sw ...

  4. bzoj2965

    http://www.lydsy.com/JudgeOnline/problem.php?id=2965 http://www.tsinsen.com/A1385 平面图网络流. 首先我们要将平面图转 ...

  5. bzoj4948: World Final2017 A

    求简单多边形内的最长线段长度 显然存在一组最优解,使其所在直线经过多边形的两个端点,枚举这两个端点,求出直线和多边形的有效交点,从而得出直线有哪些部分在多边形内(含边界). 由于多边形的一些边可能与直 ...

  6. 21天学习caffe(一)

    ubuntu环境安装caffe1 安装依赖 apt-get install libatlas-base-dev apt-get install python-dev apt-get install l ...

  7. 【智能算法】用模拟退火(SA, Simulated Annealing)算法解决旅行商问题 (TSP, Traveling Salesman Problem)

    喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 文章声明 此文章部分资料和代码整合自网上,来源太多已经无法查明出处,如侵犯您的权利,请联系我删除. 01 什么是旅行商问题(TS ...

  8. Codeforces Problem 598E - Chocolate Bar

    Chocolate Bar 题意: 有一个n*m(1<= n,m<=30)的矩形巧克力,每次能横向或者是纵向切,且每次切的花费为所切边长的平方,问你最后得到k个单位巧克力( k <= ...

  9. 【模拟退火】Petrozavodsk Winter Training Camp 2017 Day 1: Jagiellonian U Contest, Monday, January 30, 2017 Problem F. Factory

    让你在平面上取一个点,使得其到给定的所有点的距离和最小. 就是“费马点”. 模拟退火……日后学习一下,这是从网上扒的,先存下. #include<iostream> #include< ...

随机推荐

  1. 权威的国际敏捷认证Certified Scrum Master (CSM)

    权威的国际敏捷认证Certified Scrum Master (CSM) A. 认证前 在学习Certified Scrum Master (CSM)之前,你需要了解: 什么是CSM CSM认证与其 ...

  2. Vue【你知道吗?】

    前言 Vue的由来 Vue最早发布于2014年左右,作者是美中国学生尤雨溪.Vue 的定位就是为前端开发提供一个低门槛,高效率,但同时又能够伴随用户成长的框架 尤雨溪谈Vue.js :缔造自由与真我 ...

  3. 百度paddlepaddle学习体会

    一个偶然从微信公众号中刷到了<python小白逆袭A1大神>的文章,让我不经意的邂逅了飞桨(paddlepaddle),通过加入飞桨训练营一周的学习.实践,对飞桨有了很多的了解(飞桨官网: ...

  4. Netty 中的心跳检测机制

    心跳检测一般存在于建立长连接 或者 需要保活的场景. 心跳的使用场景 长连接的应用场景非常的广泛,比如监控系统,IM系统,即时报价系统,推送服务等等.像这些场景都是比较注重实时性,如果每次发送数据都要 ...

  5. 9个小技巧让你的 if else看起来更优雅

    if else 是我们写代码时,使用频率最高的关键词之一,然而有时过多的 if else 会让我们感到脑壳疼,例如下面这个伪代码: 是不是很奔溃?虽然他是伪代码,并且看起来也很夸张,但在现实中,当我们 ...

  6. sqli lab less-5-6

    less-5 基于报错的注入 基于报错可以爆出当前数据库名等等 id=2' and extractvalue(1, concat(0x7c,(select user())));-- # ?id=2' ...

  7. vagrant + 宝塔 环境搭建遇到的一些问题

    1.js时间戳单位为毫秒,php时间戳为秒. 2.tp里的where()方法如果where("id=".$id)不能用的话就用数组形式的:where(array("id& ...

  8. Cent OS 7 搭建MySQL

    搭建数据库服务器 版本众多,但为了追求稳定选择的是5.7 在使用YUM REPOSITORY官方给出的版本如下: The MySQL Yum repository includes the lates ...

  9. http的长连接与端连接

    长连接的定义:  HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包.不四次握手),等待 ...

  10. 【shell】shell脚本入门

    1. 前言 1.1 为什么学习shell编程 Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具,Linux/UNIX系统的底层及基础应用软件的核心大部分涉及Shell脚 ...