prow2012-A3-0021

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

类似凸包的扫描方法,每次把凹的维护成凸的,就是最短距离。

{{{

#include <stdio.h>
#include <math.h>
#include <map>
#include <algorithm>
#include <string.h>
using namespace std;
double X[1000000],Y[1000000];
bool ral(int i,int j,int k){
    return (X[j]-X[i])*(Y[k]-Y[i])>(X[k]-X[i])*(Y[j]-Y[i]);
}
double calc(int i,int j){
    return sqrt((X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]));
}
int Q[1000000];
int main(){
    int N,i,L,R;
    while(scanf("%d",&N)!=EOF){
        for (i=0;i<N;i++)
            scanf("%lf%lf",&X[i],&Y[i]);
        Q[0] = 0;
        L = 0,R = 1;
        for (i=1;i<N;i++)
        {
            while(L<R-1&&!ral(Q[R-2],i,Q[R-1]))
                R--;
            Q[R++] = i;
        }
        double ans = 0;
        for (i=1;i<R;i++)
            ans+=calc(Q[i-1],Q[i]);
        printf("%.2lf\n",ans);
    }



}

}}}

类似凸包的扫描方法,每次把凹的维护成凸的,就是最短距离。

#include <stdio.h>
#include <math.h>
#include <map>
#include <algorithm>
#include <string.h>
using namespace std;
double X[1000000],Y[1000000];
bool ral(int i,int j,int k){
    return (X[j]-X[i])*(Y[k]-Y[i])>(X[k]-X[i])*(Y[j]-Y[i]);
}
double calc(int i,int j){
    return sqrt((X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]));
}
int Q[1000000];
int main(){
    int N,i,L,R;
    while(scanf("%d",&N)!=EOF){
        for (i=0;i<N;i++)
            scanf("%lf%lf",&X[i],&Y[i]);
        Q[0] = 0;
        L = 0,R = 1;
        for (i=1;i<N;i++)
        {
            while(L<R-1&&!ral(Q[R-2],i,Q[R-1]))
                R--;
            Q[R++] = i;
        }
        double ans = 0;
        for (i=1;i<R;i++)
            ans+=calc(Q[i-1],Q[i]);
        printf("%.2lf\n",ans);
    }
}