码迷,mamicode.com
首页 > 其他好文 > 详细

单位圆的最多覆盖据点 (重点需要学习!)

时间:2015-03-21 21:20:53      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:

我自己的代码,提交错误,需要修改

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <iostream>
#include <string>
#include <algorithm>
#define eps 1e-8

using namespace std;

struct point
{
	double x;
	double y;
	int w;
	point(){}
	point (double tx, double ty)
	{
	    x=tx; y=ty;
	}
}a[300+10];

double Dist(point a, point b )
{
	return sqrt( (b.x-a.x)*(b.x-a.x) + (b.y-a.y)*(b.y-a.y) );
}

point find_start(point p1, point p2)
{
/*	point p, mid, start;
	double d, aa;
	p.x=p2.x-p1.x;
	p.y=p2.y-p1.y;

	mid.x = (p1.x +p2.x)/2;
	mid.y = (p1.y +p2.y)/2;

	d = sqrt( 1-Dist(p1, mid) );//公共弦长的一半长

	if( fabs(p.y) < eps )
	{
		start.x = mid.x;
		start.y = mid.y + d;
	}
	else
	{
		aa = atan(-p.x/p.y);
		start.x = mid.x + d*cos(aa);
		start.y = mid.y + d*sin(aa);
	}
	return start; */
	point mid=point((p1.x+p2.x)/2,(p1.y+p2.y)/2);

    double angle=atan2(p1.x-p2.x,p2.y-p1.y);

    double d=sqrt(1-Dist(p1,mid)*Dist(p1,mid));

    return point(mid.x+d*cos(angle), mid.y+d*sin(angle));
}


int main()
{
    int n;
    int i, j, k;

	int ans, ans0;
	point centre;
	double tmp;

  	while(scanf("%d", &n)!=EOF)
	{
		if(n==0) break;
		for(i=0; i<n; i++)
		{
			scanf("%lf %lf %d", &a[i].x, &a[i].y, &a[i].w );
		}
		ans=0; //结果至少为1
		for(i=0; i<n; i++)
		{
			for(j=i+1; j<n; j++)
			{
				if( Dist(a[i], a[j]) > 2.0 )
					continue;
				ans0=0; //
				centre = find_start(a[i], a[j]);

				for(k=0; k<n; k++)
				{
					tmp = Dist(centre, a[k]);
					if(tmp<1.00000001)
						ans0+=a[k].w;
				}
				ans=max(ans, ans0);
			}
		}
		printf("%d\n", ans );
	}
	return 0;
}

 上述方法理论上的处理数据量不大

还有另外一种方法:可以参考如下博客

http://blog.csdn.net/acm_cxlove/article/details/7894310

 

hihocoder #1064 解题博客:地址:http://blog.csdn.net/u014076176/article/details/39825957

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define ll long long
#define db double
#define PB push_back
#define lson k<<1
#define rson k<<1|1
using namespace std;

const int N = 2005;
const db PI = acos(-1.0);
const db eps = 1e-8;

int sgn(db t)
{
    return t<-eps?-1:t>eps;
}

struct Point
{
    db x,y;
    int w;
    Point (db _x=0,db _y=0):x(_x),y(_y) {}
    void input()
    {
        scanf("%lf%lf%d",&x,&y,&w);
    }
    db len2()
    {
        return x*x+y*y;
    }
    db len()
    {
        return sqrt(len2());
    }
    Point operator - (const Point &t) const
    {
        return Point(x-t.x,y-t.y);
    }
    bool operator == (const Point &t) const
    {
        return sgn(x-t.x)==0&&sgn(y-t.y)==0;
    }
    db operator * (const Point &t) const
    {
        return x*t.y-t.x*y;
    }
} p[N];

struct node
{
    db thta;
    int w;
    bool operator < (const node &t) const
    {
        if(thta==t.thta) return w>t.w;
        return thta<t.thta;
    }
} jd[N*4];

int ln;
void add(db thta,int w)
{
    jd[ln].thta=thta,jd[ln++].w=w;
    jd[ln].thta=thta+PI*2,jd[ln++].w=w;
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0; i<n; i++) p[i].input();
    Point px;
    int ans=0;
    for(int i=0; i<n; i++)
    {
        px=Point(p[i].x+1.0,p[i].y);
        ln=0;
        int nw=p[i].w;
        for(int j=0; j<n; j++)
        {
            if(i!=j)
            {
                db d=(p[i]-p[j]).len();
                if(d>2.0) continue;
                db thta=atan2((p[j]-p[i]).y,(p[j]-p[i]).x);
                db th=acos(d/2.0);
                add(thta-th,p[j].w),add(thta+th,-p[j].w);
            }
        }
        sort(jd,jd+ln);
        int mm=nw;
        for(int j=0; j<ln; j++)
            nw+=jd[j].w,mm=max(mm,nw);
        ans=max(ans,mm);
    }
    printf("%d\n",ans);
    return 0;
}

 

单位圆的最多覆盖据点 (重点需要学习!)

标签:

原文地址:http://www.cnblogs.com/yspworld/p/4356169.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!