hdu 4410 Boomerang (2012杭州网络赛1001)

这题简直是个大坑,比赛时做了两个多小时,写了两百多行代码,各种调,就是没做出来。。。

比完赛晚上十点多开始重写,写到半夜一点,终于过了!!!

 思路:枚举所有情况,n=4一种,n=6一种,n=8四种。

 

先给组数据

8 -3 9 0 9 0 0 9 0 9 -2 1 -2 1 -1 -3 -1
8 -3 9 0 9 0 0 9 0 9 -4 1 -4 1 -1 -3 -1
8 3 0 4 0 4 1 8 1 8 2 4 2 4 3 3 3
8 0 0 6 0 6 3 10 3 10 4 5 4 5 2 0 2
8 0 0 2 0 2 19 3 19 3 40 1 40 1 20 0 20
0

结果是

3.16
4.00
2.24
2.24
2.24

 

下面是代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const double EP=1e-8;
struct Point{
    int x, y;
}p[15], pt[15];
struct Segline{
    Point s, e;
}s1, s2;
int n;
void init(){
    for(int i=0; i<n; i++){
        scanf("%d%d", &p[i].x, &p[i].y);
    }
}
double x_mult(Point sp, Point ep, Point op){
    return 1.0*(sp.x-op.x)*(ep.y-op.y)-1.0*(sp.y-op.y)*(ep.x-op.x);
}
double dist(Point a,Point b){
    return sqrt(1.0*(a.x-b.x)*(a.x-b.x)+1.0*(a.y-b.y)*(a.y-b.y));
}
int pre(int i){return (i-1+n)%n;}
int next(int i){return (i+1)%n;}
bool intersect(Segline l1, Segline l2){
    if((x_mult(l1.s,l2.e,l2.s)*x_mult(l1.e,l2.e,l2.s)<-EP)&&
    (x_mult(l2.s,l1.e,l1.s)*x_mult(l2.e,l1.e,l1.s)<-EP))
    return true;
    return false;
}
bool is_cancave(int i){
    if(x_mult(p[pre(i)], p[i], p[next(i)])<0)
    return true;
    else return false;
}
bool seg_cross(int t1, int t2){
    s1.s=p[t1];s1.e=p[t2];
    for(int i=0; i<n; i++){
        s2.s=p[i];s2.e=p[(i+1)%n];
        if(intersect(s1, s2))
        return true;
    }
    return false;
}

void solve(){
    double ans, tmp;
    int i, flag[12], cnt=0, mid;
    for(i=0; i<n; i++){
        if(x_mult(p[pre(i)], p[i], p[next(i)])>0)
        cnt++;
    }
    if(cnt<=4){
        for(i=0; i<n; i++){
            pt[n-i-1]=p[i];
        }
        memcpy(p, pt, sizeof(pt));
    }
    cnt=0;
    if(n==4){
        ans=min(dist(p[0], p[1]), dist(p[1], p[2]));
    }
    else if(n==6){
        for(i=0; i<n; i++){
            if(is_cancave(i)){
                ans=min(dist(p[(i+3)%n], p[i]), min(dist(p[(i+3)%n], p[(i+4)%n]), dist(p[(i+3)%n], p[(i+2)%n])));
            }
        }
    }
    else if(n==8){
        for(i=0; i<n; i++){
            if(is_cancave(i))
                flag[cnt++]=i;
        }
        if(flag[1]<flag[0])swap(flag[0], flag[1]);
        if(flag[1]-flag[0]==2||flag[1]-flag[0]==n-2){
            if(flag[1]-flag[0]==2)mid=(flag[0]+1)%n;
            else mid=(flag[0]-1+n)%n;
            ans=min(min(dist(p[(mid+3)%n], p[(mid+4)%n]), dist(p[(mid-3+n)%n], p[(mid+4)%n]))
                    , min(dist(p[(mid+1)%n], p[(mid+4)%n]), dist(p[(mid-1+n)%n], p[(mid+4)%n])));
        }
        else if(flag[1]-flag[0]==4||flag[1]-flag[0]==n-4){
            if(p[(flag[1]+1)%n].x==p[(flag[1]+2)%n].x){

                tmp=fabs(0.0+p[(flag[1]+1)%n].x-p[(flag[1]-2+n)%n].x);
                tmp=min(tmp, fabs(0.0+p[(flag[1]+2)%n].y-p[(flag[1]-1+n)%n].y));
            }
            else {
                tmp=fabs(0.0+p[(flag[1]+1)%n].y-p[(flag[1]-2+n)%n].y);
                tmp=min(tmp, fabs(0.0+p[(flag[1]+2)%n].x-p[(flag[1]-1+n)%n].x));
            }
            ans=tmp;
            double t1, t2, t3, t4;
            t1=dist(p[(flag[1]+3)%n], p[flag[1]]);t2=dist(p[(flag[1]-3+n)%n], p[flag[1]]);
            t3=dist(p[(flag[0]+3)%n], p[flag[0]]);t4=dist(p[(flag[0]-3+n)%n], p[flag[0]]);
            if(seg_cross((flag[1]+3)%n, flag[1]))t1=min(dist(p[flag[0]], p[(flag[1]+1)%n]), dist(p[(flag[1]+1)%n], p[(flag[1]+2)%n]));
            if(seg_cross((flag[1]-3+n)%n, flag[1]))t2=min(dist(p[flag[0]], p[(flag[1]-1+n)%n]), dist(p[(flag[1]-1+n)%n], p[(flag[1]-2+n)%n]));
            if(seg_cross((flag[0]+3)%n, flag[0]))t3=min(dist(p[flag[1]], p[(flag[0]+1)%n]), dist(p[(flag[0]+1)%n], p[(flag[0]+2)%n]));
            if(seg_cross((flag[0]-3+n)%n, flag[0]))t4=min(dist(p[flag[1]], p[(flag[0]-1+n)%n]), dist(p[(flag[0]-1+n)%n], p[(flag[0]-2+n)%n]));
            tmp=max(min(t1, t4), min(t3, t2));
            ans=min(ans, tmp);
        }
        else if(flag[1]-flag[0]==1||flag[1]-flag[0]==n-1){
            if(flag[1]-flag[0]==1){
                tmp=min(max(dist(p[(flag[0]-2+n)%n], p[(flag[0]-3+n)%n]), dist(p[(flag[1]+2)%n], p[(flag[1]+3)%n]))
                    , dist(p[(flag[0]-3)%n], p[(flag[1]+3)%n]));
                ans=min(tmp, max(dist(p[(flag[0])%n], p[(flag[0]-3+n)%n]), dist(p[(flag[1])%n], p[(flag[1]+3)%n])));
            }
            else {
                tmp=min(max(dist(p[(flag[1]-2+n)%n], p[(flag[1]-3+n)%n]), dist(p[(flag[0]+2)%n], p[(flag[0]+3)%n]))
                    , dist(p[(flag[1]-3)%n], p[(flag[0]+3)%n]));
                ans=min(tmp, max(dist(p[(flag[1])%n], p[(flag[1]-3+n)%n]), dist(p[(flag[0])%n], p[(flag[0]+3)%n])));
            }
        }
        else {
            if(flag[1]-flag[0]==3){
                if(p[(flag[0]+1)%n].x==p[(flag[0]+2)%n].x)
                    tmp=fabs(0.0+p[(flag[0]+1)%n].x-p[(flag[0]-2+n)%n].x);
                else tmp=fabs(0.0+p[(flag[0]+1)%n].y-p[(flag[0]-2+n)%n].y);
                ans=min(tmp, min(dist(p[(flag[0])%n], p[(flag[0]-3+n)%n]), dist(p[(flag[1])%n], p[(flag[1]+3)%n])));
            }
            else {
                if(p[(flag[1]+1)%n].x==p[(flag[1]+2)%n].x)
                    tmp=fabs(0.0+p[(flag[1]+1)%n].x-p[(flag[1]-2+n)%n].x);
                else tmp=fabs(0.0+p[(flag[1]+1)%n].y-p[(flag[1]-2+n)%n].y);
                ans=min(tmp, min(dist(p[(flag[1])%n], p[(flag[1]-3+n)%n]), dist(p[(flag[0])%n], p[(flag[0]+3)%n])));
            }
        }
    }
    printf("%.2f\n", ans);
}

int main(){
    //freopen("1.txt", "r", stdin);
    while(scanf("%d", &n)&&n){
        init();
        solve();
    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值