题目链接:
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; }
时间: 2024-10-10 21:34:51