UVALive - 4062 You are around me ...

8 篇文章 0 订阅
6 篇文章 0 订阅

几何+二分+优化

这种题做起来其实挺爽的,做完之后特有成就感,也学到了很多东西。

首先要对点的坐标进行旋转,这里是二维的,还可以有三维甚至更多的,牵扯到线性代数知识。。。越来越觉得数学太重要了。。为什么一开始学数学的时候老师没有告诉我们数学的用处之大呢。。。。

然后是二分,题目中说对精度要求不高,但还是必须小于1E-9

但只有这些会超时,解决办法是按横坐标排序,中心距离大于当前a的二倍的可以忽略不考虑。。

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#define MAX 16000
#define INF 1e11
#define EPS 1e-9
#define PI 3.1415926535897
using namespace std;

struct node
{
    double x,y;
    bool operator<(node other)
    {
        return x<other.x;
    }
}s[MAX];

double front,rear,mid,theta,e,sinn,coss;

int dist1(int a,int b)
{
    double help1,help2,dist;
    help1=(s[a].x-s[b].x),help2=(s[a].y-s[b].y);
    dist=help1*help1+help2*help2;
    if(dist<=4*mid*mid)
        return 1;
    else
        return 0;
}


int dist2(int a,int b)
{
    double x=(s[a].x+s[b].x)/2,y=(s[a].y+s[b].y)/2,help1,help2;
    help1=(x-s[a].x),help2=(y-s[a].y);
    if((1-e*e)*(help1*help1-mid*mid)+(help2*help2)<0)
        return 1;
    else
        return 0;
}

int main()
{
    int n,i,j,t=1;
    double a,b;
    while(scanf("%d %lf %lf",&n,&e,&theta)&&n)
    {
        sinn=sin(theta/180*PI),coss=cos(theta/180*PI);
        for(i=0;i<n;i++)
        {
            scanf("%lf %lf",&a,&b);
            s[i].x=a*coss+b*sinn,s[i].y=b*coss-a*sinn;
        }
        front=0,rear=INF;
        sort(s,s+n);
        while(rear-front>EPS)
        {
            mid=(front+rear)/2;
            for(i=0;i<n;i++)
            {
                for(j=i+1;j<n;j++)
                {
                    if(s[j].x-s[i].x>mid*2+0.1)
                        break;
                    if(dist1(i,j))
                    {
                        if(dist2(i,j))
                        {
                            rear=mid;
                            goto next;
                        }
                    }
                }
            }
            front=mid;
            next:
                { }
        }
        printf("Case %d:\n%.6lf\n",t++,PI*front*front*sqrt(1-e*e));
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值