hdu 3847 2011world finals
偶尔逛到这题,是2011年世界总决赛的题目,怀着一丝敬畏和期待开始看这道题目
二维平面内一个多边形,可以任意旋转,使得可以将其扔进一个宽为w的槽,求w的最小值
idea:
开始的时候随便画了画草图,假设最后最优的情况是两个点分别在槽的两边,则一定可以绕其中的一个点旋转一个角度使得产生空隙(纸上画一画就知道了),此时的答案应该更小才是,进一步可以发现一定能够将一条边转到槽的便上,所以,有方案了。
先求土包,枚举土包上的每条边,再枚举每个土包上的点,求出最大的距离,这些最大距离的最小值就是我们要的答案
可惜没有1A....没有判断n为0的时候停止。。囧!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include <algorithm>
using namespace std;
const double eps = 1e-8;
const double pi = acos(-1.0);
int n;
struct point {
double x, y;
point operator - (const point& t) const {
point tmp;
tmp.x = x - t.x;
tmp.y = y - t.y;
return tmp;
}
point operator + (const point& t) const {
point tmp;
tmp.x = x + t.x;
tmp.y = y + t.y;
return tmp;
}
bool operator == (const point& t) const {
return fabs(x-t.x) < eps && fabs(y-t.y) < eps;
}
}p[220];
bool cmpxy(point a,point b)
{
if(a.y!=b.y) return a.y<b.y;
return a.x<b.x;
}
double xmult(point p1,point p2,point p0){
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
inline double cross(point a, point b, point c) { // 叉积
return (b.x-a.x)*(c.y-a.y) - (c.x-a.x)*(b.y-a.y);
}
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));
}
void Grahamxy(point *p, int &n) { // 水平序(住:两倍空间)
if ( n < 3 )
return;
int i, m=0, top=1;
sort(p, p+n, cmpxy);
for (i=n; i < 2*n-1; i++)
p[i] = p[2*n-2-i];
for (i=2; i < 2*n-1; i++) {
while ( top > m && cross(p[top], p[i], p[top-1]) < eps )
top--;
p[++top] = p[i];
if ( i == n-1 ) m = top;
}
n = top;
}
inline double PLdis(point p,point l1,point l2){ // 点线距离
return fabs(cross(p,l1,l2))/dis(l1,l2);
}
void judge(point a,point b,double &len)
{
double max=0;
for(int i=0;i<n;i++)
{
double tmp=PLdis(p[i],a,b);
if(tmp>max)
max=tmp;
}
len=max;
}
double solve()
{
int i,j;
double tmp;
double ans=((__int64)1<<62);
for(i=0;i<n;i++)
{
judge(p[i],p[i+1],tmp);
if(tmp<ans)
ans=tmp;
}
return ans;
}
int main()
{
int i,j;
int cases=1;
while(scanf("%d",&n),n)
{
for(i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
Grahamxy(p,n);
p[n]=p[0];
double ans=solve();
printf("Case %d: %.2lf\n",cases++,ans+0.005);
}
return 0;
}