[hdu3644 A Chocolate Manufacturer's Problem]模拟退火,简单多边形内最大圆
题意:判断简单多边形内是否可以放一个半径为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]模拟退火,简单多边形内最大圆的更多相关文章
- HDU - 3644:A Chocolate Manufacturer's Problem(模拟退火, 求多边形内最大圆半径)
pro:给定一个N边形,然后给半径为R的圆,问是否可以放进去. 问题转化为多边形的最大内接圆半径.(N<50): sol:乍一看,不就是二分+半平面交验证是否有核的板子题吗. 然而事情并没有那 ...
- Codeforces Beta Round #2 C. Commentator problem 模拟退火
C. Commentator problem 题目连接: http://www.codeforces.com/contest/2/problem/C Description The Olympic G ...
- 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 ...
- bzoj2965
http://www.lydsy.com/JudgeOnline/problem.php?id=2965 http://www.tsinsen.com/A1385 平面图网络流. 首先我们要将平面图转 ...
- bzoj4948: World Final2017 A
求简单多边形内的最长线段长度 显然存在一组最优解,使其所在直线经过多边形的两个端点,枚举这两个端点,求出直线和多边形的有效交点,从而得出直线有哪些部分在多边形内(含边界). 由于多边形的一些边可能与直 ...
- 21天学习caffe(一)
ubuntu环境安装caffe1 安装依赖 apt-get install libatlas-base-dev apt-get install python-dev apt-get install l ...
- 【智能算法】用模拟退火(SA, Simulated Annealing)算法解决旅行商问题 (TSP, Traveling Salesman Problem)
喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 文章声明 此文章部分资料和代码整合自网上,来源太多已经无法查明出处,如侵犯您的权利,请联系我删除. 01 什么是旅行商问题(TS ...
- Codeforces Problem 598E - Chocolate Bar
Chocolate Bar 题意: 有一个n*m(1<= n,m<=30)的矩形巧克力,每次能横向或者是纵向切,且每次切的花费为所切边长的平方,问你最后得到k个单位巧克力( k <= ...
- 【模拟退火】Petrozavodsk Winter Training Camp 2017 Day 1: Jagiellonian U Contest, Monday, January 30, 2017 Problem F. Factory
让你在平面上取一个点,使得其到给定的所有点的距离和最小. 就是“费马点”. 模拟退火……日后学习一下,这是从网上扒的,先存下. #include<iostream> #include< ...
随机推荐
- 权威的国际敏捷认证Certified Scrum Master (CSM)
权威的国际敏捷认证Certified Scrum Master (CSM) A. 认证前 在学习Certified Scrum Master (CSM)之前,你需要了解: 什么是CSM CSM认证与其 ...
- Vue【你知道吗?】
前言 Vue的由来 Vue最早发布于2014年左右,作者是美中国学生尤雨溪.Vue 的定位就是为前端开发提供一个低门槛,高效率,但同时又能够伴随用户成长的框架 尤雨溪谈Vue.js :缔造自由与真我 ...
- 百度paddlepaddle学习体会
一个偶然从微信公众号中刷到了<python小白逆袭A1大神>的文章,让我不经意的邂逅了飞桨(paddlepaddle),通过加入飞桨训练营一周的学习.实践,对飞桨有了很多的了解(飞桨官网: ...
- Netty 中的心跳检测机制
心跳检测一般存在于建立长连接 或者 需要保活的场景. 心跳的使用场景 长连接的应用场景非常的广泛,比如监控系统,IM系统,即时报价系统,推送服务等等.像这些场景都是比较注重实时性,如果每次发送数据都要 ...
- 9个小技巧让你的 if else看起来更优雅
if else 是我们写代码时,使用频率最高的关键词之一,然而有时过多的 if else 会让我们感到脑壳疼,例如下面这个伪代码: 是不是很奔溃?虽然他是伪代码,并且看起来也很夸张,但在现实中,当我们 ...
- sqli lab less-5-6
less-5 基于报错的注入 基于报错可以爆出当前数据库名等等 id=2' and extractvalue(1, concat(0x7c,(select user())));-- # ?id=2' ...
- vagrant + 宝塔 环境搭建遇到的一些问题
1.js时间戳单位为毫秒,php时间戳为秒. 2.tp里的where()方法如果where("id=".$id)不能用的话就用数组形式的:where(array("id& ...
- Cent OS 7 搭建MySQL
搭建数据库服务器 版本众多,但为了追求稳定选择的是5.7 在使用YUM REPOSITORY官方给出的版本如下: The MySQL Yum repository includes the lates ...
- http的长连接与端连接
长连接的定义: HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包.不四次握手),等待 ...
- 【shell】shell脚本入门
1. 前言 1.1 为什么学习shell编程 Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具,Linux/UNIX系统的底层及基础应用软件的核心大部分涉及Shell脚 ...