zoukankan      html  css  js  c++  java
  • 傻逼数学题(math)

    傻逼数学题
    题目描述

    由于乱码,复制不下来,只好截图了

    输入格式

    第一行一个正整数n

    接下来n行每行两个整数x,y,表示第i个点的坐标

    输出格式

    一行一个数表示最小距离和,保留6位小数

    样例输入

    4

    1 1

    2 3

    3 3

    3 4

    样例输出

    3.414214

    样例解释

    数据约定

    对于30%的数据,n<=400.

    对于100%的数据,3<=n<=200000.

    反思

    这一题其实算是个原题了,就是昨天的最近点对,只不过我们需要寻找的变成了3个,思路都是差不多的,但是我就是觉得太复杂,所以没有去实现.所以在考场上我就只打了一个n三方的暴力,也就只拿了30pts,所以我们有任务千万别拖欠,一朝拖欠,就要付出惨痛的代价......

    思路

    就是原题啦,我们只需要在最近点对的基础改几个地方

    1.边界条件(l+2==r)因为有3个

    2.在越过中间寻找时,注意3重循环

    代码
     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define FOR(i,a,b) for(register int i=a;i<=b;i++)
     4 #define ROF(i,a,b) for(register int i=a;i>=b;i--)
     5 using namespace std;
     6 int n;
     7 const ll N=1000000000000;
     8 int tmpt[200100];
     9 struct ss
    10 {
    11     double x;double y;
    12 }pot[200100];
    13 int scan()
    14 {
    15     int as=0,f=1;
    16     char c=getchar();
    17     while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
    18     while(c>='0'&&c<='9'){as=(as<<3)+(as<<1)+c-'0';c=getchar();}
    19     return as*f;
    20 }
    21 bool cmp(ss i,ss j)
    22 {
    23     return i.x<j.x;
    24 }
    25 bool cmp2(int i,int j)
    26 {
    27     return pot[i].y<pot[j].y;
    28 }
    29 double dis(int i,int j)
    30 {
    31     double f=sqrt(double((pot[i].x-pot[j].x)*(pot[i].x-pot[j].x)+(pot[i].y-pot[j].y)*(pot[i].y-pot[j].y)));
    32     return f; 
    33 }
    34 double par(int l,int r)
    35 {
    36 //    cout<<"y"<<endl;
    37     double d=N;
    38     if(l==r||l+1==r) return d;
    39     if(l+2==r) return dis(l,r)+dis(l+1,r)+dis(l+1,l);
    40     int mid=(l+r)>>1;//除以2
    41     double d1=par(l,mid);
    42     double d2=par(mid+1,r);
    43     d=min(d1,d2);
    44     int k=0;
    45     FOR(i,l,r)
    46     {
    47         if(abs(pot[i].x-pot[mid].x)<=d)
    48         {
    49             tmpt[++k]=i;//保存位置
    50         }
    51     }
    52     sort(tmpt+1,tmpt+k+1,cmp2);
    53     FOR(i,1,k)
    54     {
    55         FOR(j,i+1,k)
    56         {
    57             if(pot[tmpt[j]].y-pot[tmpt[i]].y>=d/2) break;
    58             FOR(j1,j+1,k)
    59             {
    60                 if(pot[tmpt[j1]].y-pot[tmpt[i]].y>=d/2) break;
    61                 double d3=dis(tmpt[i],tmpt[j])+dis(tmpt[i],tmpt[j1])+dis(tmpt[j1],tmpt[j]);
    62                 d=min(d,d3);
    63             }
    64         }
    65     }
    66     return d;
    67 }
    68 int main()
    69 {
    70 //    freopen("copy.in","r",stdin);
    71 //    freopen("copy.out","w",stdout);
    72     n=scan();
    73     FOR(i,1,n)
    74     {
    75         scanf("%lf%lf",&pot[i].x,&pot[i].y);
    76     }
    77     sort(pot+1,pot+n+1,cmp);
    78     double h=par(1,n);
    79     printf("%.6lf",h);//求1~n的最近点对
    80     return 0;
    81 }
    View Code
  • 相关阅读:
    Opencv在mac系统的安装与试用
    VINS 估计器之检查视差
    C语言——第零次作业
    C语言博客05指针
    循环结构
    C语言博客作业数组
    函数3
    C博客作业01分支、顺序结构
    group by的查询
    layui多张图片上传最多9张(新增和修改时的显示问题)
  • 原文地址:https://www.cnblogs.com/KSTT/p/10363084.html
Copyright © 2011-2022 走看看