UVA 10005 Packing polygons(最小圆覆盖)

裸的模板题

AC代码:

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<algorithm>
  4 #include<iostream>
  5 #include<cstring>
  6 using namespace std;
  7 typedef long long ll;
  8 const double eps = 1e-8;
  9 const double pi = acos(-1.0);
 10 const int maxp = 5000;
 11 int sgn(double x)
 12 {
 13     if(fabs(x) < eps) return 0;
 14     else return x < 0 ? -1 : 1;
 15 }
 16 struct Point{
 17     double x, y;
 18     Point(){}
 19     Point(double _x, double _y){
 20         x = _x, y = _y;
 21     }
 22     void input(){
 23         scanf("%lf%lf", &x, &y);
 24     }
 25     bool operator == (Point b) const{
 26         return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
 27     }
 28     bool operator < (Point b)const{
 29         return sgn(x - b.x) == 0 ? sgn(y - b.y < 0) : x < b.x;
 30     }
 31     Point operator - (const Point &b)const{
 32         return Point(x - b.x, y - b.y);
 33     }
 34     //²æ»ý
 35     double operator ^(const Point &b){
 36         return x * b.y - y * b.x;
 37     }
 38     //µã»ý
 39     double operator *(const Point &b){
 40         return x * b.x + y * b.y;
 41     }
 42     double len(){
 43         return hypot(x, y);
 44     }
 45     double len2(){
 46     return x * x + y * y;
 47     }
 48     double distant(Point p){
 49         return hypot(x - p.x, y - p.y);
 50     }
 51     Point operator + (const Point &b)const{
 52         return Point (x + b.x, y + b.y);
 53     }
 54     Point operator * (const double &k)const{
 55         return Point(x * k, y * k);
 56     }
 57     Point operator / (const double &k)const{
 58         return Point(x / k, y / k);
 59     }
 60     Point rotate(Point p, double angle){
 61         Point v = (*this) - p;
 62         double c = cos(angle), s = sin(angle);
 63         return Point(p.x + v.x * c - v.y * s, p.y + v.x * s + v.y * c);
 64     }
 65 };
 66 struct polygon{
 67     int n;
 68     Point p[maxp];
 69     void add(Point q){
 70         p[n ++] = q;
 71     }
 72     void input(int _n){
 73         n = _n;
 74         for(int i = 0;i < n;i++) p[i].input();
 75     }
 76     Point circumcenter(const Point &a,const Point &b,const Point &c) {
 77         //返回三角形的外心
 78         Point ret;
 79         double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1*a1+b1*b1) / 2;
 80         double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2*a2 + b2*b2) / 2;
 81         double d = a1 * b2 - a2 * b1;
 82         ret.x = a.x + (c1*b2 - c2*b1) / d;
 83         ret.y = a.y + (a1*c2 - a2*c1) / d;
 84         return ret;
 85     }
 86     void min_cover_circle(Point &c,double &r) { // p为点的集合;c为圆心,r为半径
 87         random_shuffle(p,p+n);
 88         c = p[0];
 89         r = 0;
 90         for(int i = 1; i < n; i++) {
 91             if(c.distant(p[i]) > r + eps) {
 92                 c = p[i];
 93                 r = 0;
 94                 for(int j = 0; j < i; j++){
 95                     if(c.distant(p[j]) > r + eps) {
 96                         c.x = (p[i].x + p[j].x) / 2;
 97                         c.y = (p[i].y + p[j].y) / 2;
 98                         r = c.distant(p[j]);
 99                         for(int k = 0; k < j; k++) {
100                             if(c.distant(p[k]) > r + eps) {
101                             c = circumcenter(p[i],p[j],p[k]);
102                             r = c.distant(p[i]);
103                             }
104                         }
105                     }
106                 }
107             }
108         }
109     }
110 };
111 int main()
112 {
113     int n;
114     double r;
115     double ans;
116     while(~scanf("%d",&n) &&n)
117     {
118         polygon a;
119         Point c;
120         a.input(n);
121         scanf("%lf",&r);
122         a.min_cover_circle(c,ans);
123         if(ans <= r) printf("The polygon can be packed in the circle.\n");
124         else printf("There is no way of packing that polygon.\n");
125     }
126     return 0;
127 }

 

转载于:https://www.cnblogs.com/Carered/p/11406542.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值