hdu 3644(几何模拟退火
2017-07-16 16:22
337 查看
传送门
题意: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 ProblemTime 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. n 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 |
明显在多边形里求一个点到这个多边形所有边的距离能<=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 ProblemTime 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. n 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 |
相关文章推荐
- hdu 3644(几何模拟退火
- hdu 3644(几何模拟退火
- hdu 3644(几何模拟退火
- hdu 3644(几何模拟退火
- hdu 3644(几何模拟退火
- hdu 3644(几何模拟退火
- HDU 3644 计算几何 模拟退火
- hdu 3644(几何模拟退火
- hdu 3644(几何模拟退火
- hdu 3644(几何模拟退火
- hdu 3644(几何模拟退火
- hdu 3644(几何模拟退火
- hdu 3644(几何模拟退火
- HDU 5017 Ellipsoid (计算几何,模拟退火)
- HDU 5017 Ellipsoid (计算几何,模拟退火)
- hdu--5128--计算几何<算不上.暴力模拟> && hdu--5131--初级cmp
- HDU 3932 模拟退火
- 【几何模拟】hdu 3286
- hdu 5017 模拟退火求最值
- [几何 模拟退火 || 随机增量法] Codeforces 442E #253 (Div. 1) E. Gena and Second Distance