hdu 4643 GSM

紀念一下此題,雖然不難,但是寫起來比較麻煩,很多人直接套了許多模板過的,標程是採用二分的方法,我是採用一般方式進行遞推,不斷尋找中垂線。順便把標程貼上

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
struct Line
{
    double b,k;
    int f;
};
double city[55][2];
double st[55][2];
int n,m;
bool v[55];
int solve(int A,int B)
{
    if(A==B) return 0;
    double x=city[A][0],y=city[A][1];
    int pos=-1,Sum=0;
    double a,b;
    double s=10000000;
    for(int i=0; i<m; ++i)
    {
        double c=sqrt((x-st[i][0])*(x-st[i][0])+(y-st[i][1])*(y-st[i][1]));
        if(c<s) s=c,pos=i;
    }
    x=st[pos][0],y=st[pos][1];
    memset(v,0,sizeof(v));
    v[pos]=1;
    Line li_ci;
    if(fabs(city[B][0]-city[A][0])<0.0000001) li_ci.f=-1,li_ci.b=city[B][0];
    else
    {
        li_ci.k=(city[A][1]-city[B][1])/(city[A][0]-city[B][0]);
        li_ci.b=city[A][1]-li_ci.k*city[A][0];
        li_ci.f=0;
    }
    double u=city[A][0];
    if(li_ci.f==-1) u=city[A][1];
    while(1)
    {
        int flag=0,p=-1;
        double q;
        for(int j=0; j<m; ++j)
            if(!v[j])
            {
                Line st_st;
                if(fabs(y-st[j][1])<0.0000001) st_st.f=-1,st_st.b=(x+st[j][0])/2;
                else
                {
                    st_st.f=0;
                    st_st.k=-(x-st[j][0])/(y-st[j][1]);
                    a=(y+st[j][1])/2;
                    b=(x+st[j][0])/2;
                    st_st.b=a-st_st.k*b;
                }
                if((li_ci.f==-1&&st_st.f==-1)||(!li_ci.f&&!st_st.f&&fabs(li_ci.k-st_st.k)<0.0000001)) continue;
                if(li_ci.f!=-1)
                {
                    if(st_st.f==-1) a=st_st.b;
                    else a=(st_st.b-li_ci.b)/(li_ci.k-st_st.k);
                    if(a>=max(u,city[B][0])||a<=min(u,city[B][0])) continue;
                    if(!flag) flag=1,p=j,q=a;
                    else if((u<city[B][0]&&a<q)||(u>city[B][0]&&a>q)) p=j,q=a;
                    continue;
                }
                else
                {
                    if(fabs(st_st.k)<0.0000001) a=st_st.b;
                    else a=st_st.k*li_ci.b+st_st.b;
                    if(a>=max(u,city[B][1])||a<=min(u,city[B][1])) continue;
                    if(!flag) flag=1,p=j,q=a;
                    else if((u<city[B][1]&&a<q)||(u>city[B][1]&&a>q)) p=j,q=a;
                    continue;
                }
            }
        if(p==-1) break;
        ++Sum;
        v[pos=p]=1;
        x=st[p][0],y=st[p][1];
        u=q;
    }
    return Sum;
}
int main()
{
   // freopen("in.txt","r",stdin);
   // freopen("ou.txt","w",stdout);
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1; i<=n; ++i) scanf("%lf%lf",&city[i][0],&city[i][1]);
        for(int i=0; i<m; ++i) scanf("%lf%lf",&st[i][0],&st[i][1]);
        int x,y,s;
        scanf("%d",&s);
        for(int i=1; i<=s; ++i)
        {
            scanf("%d%d",&x,&y);
                printf("%d\n",solve(x,y));
        }
    }
    return 0;
}

標程:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
#define N 53
#define eps 1e-11
#define inf 1e10

struct POINT {
    double x, y;
    POINT() {};
    POINT(double _x, double _y): x(_x), y(_y) {};
}c[N], b[N];
int n, m;


inline double dist(POINT &x, POINT &y) {
    return ((x.x-y.x)*(x.x-y.x) + (x.y-y.y)*(x.y-y.y));
}
int belong(POINT &x) {
    double r = inf, d;
    int k = 0;
    for (int i=0; i<m; i++) {
        d = dist(x, b[i]);
        if (d < r) { r = d; k = i; }
    }
    return k;
}
int work(POINT &x, POINT &y) {
    int la = belong(x), lb = belong(y);
    if (la == lb) return 0;
    if (sqrt(dist(x, y)) < eps) return 1;
    POINT t((x.x+y.x)/2.0, (x.y+y.y)/2.0);
    return work(x, t) + work(t, y);
}
int main() {
    int k, x, y;
    while (scanf("%d%d", &n, &m) == 2) {
        for (int i=0; i<n; i++) scanf("%lf%lf", &c[i].x, &c[i].y);
        for (int i=0; i<m; i++) scanf("%lf%lf", &b[i].x, &b[i].y);
        scanf("%d", &k);
        while (k--)  {
            scanf("%d%d", &x, &y);
            printf("%d\n", work(c[x-1], c[y-1]));
        }
    }

    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章