您的位置:首页 > 其它

hdu 3644(几何模拟退火

2017-07-16 16:22 204 查看
传送门

A Chocolate Manufacturer's Problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2360    Accepted Submission(s): 456


Problem Description

My mama always said:Life is like a box of chocolate, you never know what you are going to get. 

——From Forrest Gump

ACM is a chocolate manufacturer. Inspired by the famous quote above, recently, they are designing a new brand of chocolate named Life. Each piece of chocolate is a random simple polygon. After molding and shaping, every piece is put in a small box. Until you
open the box, you will not know what you will get: a huge piece or only a tiny fraction. It is really like life and that is the reason it is named for.

However, here comes a problem. The manufacturer has to print the logo on each piece of chocolate. The logo is a circle with ‘ACM’ inside. Here is an example below. It is fortunate that the logo can be printed on the chocolate.



Now the manufacturer is asking you for help. Given the information about the chocolate shape and the radius of the logo, you need to judge whether or not there is enough space to print the logo.

 

Input

The input contains no more than 20 cases, and each case is formatted as follows.



x1 y1 

x2 y2



xn yn 

r

The first line is the number of vertices of the polygon, n, which satisfies 3 ≤ n ≤ 50. Following n lines are the x- and y-coordinates of the n vertices. They are float numbers and satisfy 0 ≤ xi ≤ 1000 and 0 ≤ yi ≤ 1000 (i = 1, …, n).
Line segments (xi, yi)–(xi+ 1 , yi + 1) (i = 1, …, n) and the line segment (xn, yn)–(x1, y1) form the border of the polygon. After the description of the polygon, a float
number r follows, meaning the radius of the logo( r <= 1000). 

The input ends by a single zero.

You may assume that the polygon is simple, that is, its border never crosses or touches itself.

 

Output

For each case, output “Yes” if the logo is able to be printed on the chocolate, otherwise output “No” instead.

 

Sample Input

3
0 0
0 1
1 0
0.28
3
0 0
0 1
1 0
0.3
0

 

Sample Output

Yes
No

Hint
Here is a picture illustrated the first case. It may be helpful for you to understand the problem.



 

Source

2010 Asia Regional Hangzhou Site —— Online Contest

题意:n。n个点。问这些点连起来的多边形(可能是凹的 能不能有一个R半径的圆的面积。
明显在多边形里求一个点到这个多边形所有边的距离能<=R肯定就Yes。

必须保证点在这个多边形内。

有多种方法可以判断,个人喜好。

//china no.1
#include <vector>
#include <iostream>
#include <string>
#include <map>
#include <stack>
#include <cstring>
#include <queue>
#include <list>
#include <stdio.h>
#include <set>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <iomanip>
#include <cctype>
#include <complex>
#include <sstream>
#include <time.h>
#include <functional>
using namespace std;

#define pi acos(-1)
#define endl '\n'
#define srand() srand(time(0));
#define me(x) memset(x,0,sizeof(x));
#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)
#define close() ios::sync_with_stdio(0); cin.tie(0);
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL LINF=0x3f3f3f3f3f3f3f3fLL;
const int dx[]={-1,0,1,0,-1,-1,1,1};
const int dy[]={0,1,0,-1,1,-1,1,-1};
const int maxn=1e3+5;
//const int maxx=1e5+100;
const double EPS=1e-7;
const double eps=1e-5;
const int MOD=10000007;
#define mod(x) ((x)%MOD);
template<class T>inline T min(T a,T b,T c) { return min(min(a,b),c);}
template<class T>inline T max(T a,T b,T c) { return max(max(a,b),c);}
template<class T>inline T min(T a,T b,T c,T d) { return min(min(a,b),min(c,d));}
template<class T>inline T max(T a,T b,T c,T d) { return max(max(a,b),max(c,d));}
//typedef tree<pt,null_type,less< pt >,rb_tree_tag,tree_order_statistics_node_update> rbtree;
long long gcd(long long a , long long b){if(b==0) return a;a%=b;return gcd(b,a);}
#define FOR(x,n,i) for(int i=x;i<=n;i++)
#define FOr(x,n,i) for(int i=x;i<n;i++)
#define W while

inline int Scan()
{
int res=0,ch,flag=0;
if((ch=getchar())=='-')flag=1;
else if(ch>='0' && ch<='9')res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-'0';
return flag ? -res : res;
}
int n;

struct point
{
double x, y, r;
} p[maxn], test[maxn];
inline int dblcmp( double x )
{
if( fabs(x) < eps )
return 0;
return x > 0 ? 1 : -1;
}

inline double sqr( double x )
{
return x*x;
}
/*
double X(point A,point B,point C)//差积 是否<0
{
return (B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y);
}
double len(point A,point B)//距离
{
return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}

bool cmp(point A,point B)
{
double pp=X(p[0],A,B);
if(pp>0) return 1;
if(pp<0) return 0;
return len(p[0],A)<len(p[0],B); //如果等于0 判断距离 返回小的
}
*/
double dis( point& aa, point& bb )
{
return sqrt(sqr(aa.x-bb.x)+sqr(aa.y
4000
-bb.y));
}

double cross( point& k, point& aa, point& bb )
{
return (k.x-aa.x)*(k.y-bb.y)-(k.y-aa.y)*(k.x-bb.x);
}

//线段到点的距离
double seg_point_dis( point& l1, point& l2, point& k )
{
double a, b, c;
a = dis(l1, k);
b = dis(l2, k);
c = dis(l1, l2);

//这里的判断是由余弦定理推出来的
if( dblcmp(a*a+c*c-b*b) < 0 )
return a;
else if( dblcmp(b*b+c*c-a*a) < 0 )
return b;
else
return fabs(cross(k, l1, l2)/c);
}
/*
double cal( point& t )
{
double maxc=INF;
for(int i=0; i<n; i++)
{
double z = seg_point_dis(p[i], p[i+1], t);
maxc = min(maxc, z);
}
return maxc;
}*/
void cal( point& aa )
{
double t;
aa.r = INF;
for( int i = 0; i < n; ++i )
{
t = seg_point_dis(p[i], p[i+1], aa);
aa.r = min(aa.r, t);
}
}

bool point_inside( point& aa )
{
int i, cnt = 0;
double t;

//确保p
= p[0]
for( i = 0; i < n; ++i )
{
if( (p[i].y <= aa.y && p[i+1].y > aa.y) ||
(p[i+1].y <= aa.y && p[i].y > aa.y) )
{
if( !dblcmp(p[i].y-p[i+1].y) )
{
if( dblcmp(p[i].y-aa.y) == 0 )
cnt++;
t = -INF;
}
else
t = p[i+1].x - (p[i+1].x-p[i].x)*(p[i+1].y-aa.y)/(p[i+1].y-p[i].y);

if( dblcmp( t - aa.x ) >= 0 )
cnt++;
}
}

return cnt%2;
}

double maxx, maxy, minx, miny,R;
//double r=0.8;
int main()
{
srand();

while( scanf("%d", &n), n )
{
int init_num=20;
int i, j;
maxx = maxy = 0;
minx = miny = INF;
for(i=0; i<n ;i++)
{
scanf("%lf %lf", &p[i].x, &p[i].y);
maxx = max(maxx, p[i].x);
maxy = max(maxy, p[i].y);
minx = min(minx, p[i].x);
miny = min(miny, p[i].y);
}
maxx -= minx; maxy -= miny;
p
= p[0];
for( i = 0; i < init_num; ++i )
{
test[i].x = (p[i].x+p[i+1].x)/2;
test[i].y = (p[i].y+p[i+1].y)/2;
test[i].r = 0;
}
scanf("%lf", &R);
int ok=0;
point next, temp;
double step=sqrt(maxx*maxx+maxy*maxy)/2;
//double step=double(max(maxx,maxy)/sqrt(1.0*n));//初始步长长度
while( !ok && step > eps )
{
for( i = 0; !ok && i < init_num; ++i )
{
for( j = 0; !ok && j < 50; ++j )
{
double ang=(rand()%1000+1)/1000.0*2*pi;
temp.x = test[i].x + step*cos(ang);
temp.y = test[i].y + step*sin(ang);
if( point_inside(temp) )
{
cal(temp);
if( temp.r > test[i].r )
{
test[i] = temp;
if( dblcmp(temp.r-R) >= 0 )
ok = 1;
}
}
}
}
step *= 0.50;
}

if(ok)
printf("Yes\n");
else printf("No\n");
}
}


A Chocolate Manufacturer's Problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2360    Accepted Submission(s): 456


Problem Description

My mama always said:Life is like a box of chocolate, you never know what you are going to get. 

——From Forrest Gump

ACM is a chocolate manufacturer. Inspired by the famous quote above, recently, they are designing a new brand of chocolate named Life. Each piece of chocolate is a random simple polygon. After molding and shaping, every piece is put in a small box. Until you
open the box, you will not know what you will get: a huge piece or only a tiny fraction. It is really like life and that is the reason it is named for.

However, here comes a problem. The manufacturer has to print the logo on each piece of chocolate. The logo is a circle with ‘ACM’ inside. Here is an example below. It is fortunate that the logo can be printed on the chocolate.



Now the manufacturer is asking you for help. Given the information about the chocolate shape and the radius of the logo, you need to judge whether or not there is enough space to print the logo.

 

Input

The input contains no more than 20 cases, and each case is formatted as follows.



x1 y1 

x2 y2



xn yn 

r

The first line is the number of vertices of the polygon, n, which satisfies 3 ≤ n ≤ 50. Following n lines are the x- and y-coordinates of the n vertices. They are float numbers and satisfy 0 ≤ xi ≤ 1000 and 0 ≤ yi ≤ 1000 (i = 1, …, n).
Line segments (xi, yi)–(xi+ 1 , yi + 1) (i = 1, …, n) and the line segment (xn, yn)–(x1, y1) form the border of the polygon. After the description of the polygon, a float
number r follows, meaning the radius of the logo( r <= 1000). 

The input ends by a single zero.

You may assume that the polygon is simple, that is, its border never crosses or touches itself.

 

Output

For each case, output “Yes” if the logo is able to be printed on the chocolate, otherwise output “No” instead.

 

Sample Input

3
0 0
0 1
1 0
0.28
3
0 0
0 1
1 0
0.3
0

 

Sample Output

Yes
No

Hint
Here is a picture illustrated the first case. It may be helpful for you to understand the problem.



 

Source

2010 Asia Regional Hangzhou Site —— Online Contest

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: