HDU 3458 Enumerate the Triangles(最小周长三角形)

来源:互联网 发布:尤氏 知乎 编辑:程序博客网 时间:2024/06/03 17:31

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3548


题意:

给定N个点的坐标求这些点能够成的周长最小的三角形的周长。


分析:

设三角形的三变长分别为,a,b,c;  a<b+c;L=a+b+c;

因此当我们的当前的最小周长如果小于其中一条边的二倍的话

那么很明显有这个边构成的三角形的周长一定大于现在的周长,

我们可以根据这个性质进行减枝。


代码如下:

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>using namespace std;const int maxn = 1010;struct point{    double x,y;    bool operator < (const struct point &tmp)const{        return x<tmp.x;    }}p[maxn];inline double dis(point a,point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}inline bool check(point a,point b,point c){    if((a.x-b.x)*(c.y-b.y)==(a.y-b.y)*(c.x-b.x))        return false;    return true;}int main(){    int n,t,cas=1;    scanf("%d",&t);    while(t--){        scanf("%d",&n);        for(int i=0;i<n;i++)            scanf("%lf%lf",&p[i].x,&p[i].y);        sort(p,p+n);        bool f=0;        double ans = 1000000000;        for(int i=0;i<n;i++){            for(int j=i+1;j<n;j++){                if(ans <= 2*( p[j].x - p[i].x) )break;                double dd =dis(p[i],p[j]);                for(int k=j+1;k<n;k++){                    if(ans<=2*(p[k].x-p[i].x)) break;                    if(check(p[i],p[j],p[k])){                        f=1;                        if(ans>dis(p[i],p[k])+dis(p[j],p[k])+dd)                            ans = dis(p[i],p[k])+dis(p[j],p[k])+dd;                    }                }            }        }        if(f) printf("Case %d: %.3lf\n",cas++,ans);        else printf("Case %d: No Solution\n",cas++);    }    return 0;}



0 0
原创粉丝点击