您的位置:首页 > 其它

高效算法设计专项:LA 2963

2013-06-02 12:31 309 查看
刚开始完全没思路,看了训练指南上的提示说是扫描法,然后往这方面想。仔细分析题目发现可以用O(n^2)的时间解决。不难发现可能的结果只可能是n个点两两距离的,然后可以从小到大扫描这n*(n-1)/2条边,然后维护当前符合条件的planet的个数。需要注意处理边长相等的情况。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
#define M 1010
const double eps=1e-6;
int dcmp(double x)
{
if(fabs(x)<eps) return 0;
else return x<0?-1:1;
}
struct point
{
int x,y,z,p;
} a[M];
struct edge
{
int u,v;
double l;
edge(int u=0,int v=0,double l=0):u(u),v(v),l(l){}
bool operator<(const edge& tmp) const
{return dcmp(l-tmp.l)<0;}
} e[M*M];
double length(int i,int j)
{
int x=a[i].x-a[j].x,y=a[i].y-a[j].y,z=a[i].z-a[j].z;
return sqrt(x*x+y*y+z*z);
}
int n,m;
int c[M];
int main()
{
freopen("in.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].z,&a[i].p);
c[i]=1;
}
m=0;
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
e[m++]=edge(i,j,length(i,j));
}
}
sort(e,e+m);
int ans=0,cur=0;
double len=0;
for(int i=0;i<m;i++)
{
int u=e[i].u,v=e[i].v;
double l=e[i].l;
if(a[u].p!=a[v].p)
{
c[u]--;
c[v]--;
if(c[u]==-1) cur++;
if(c[v]==-1) cur++;
}
else
{
c[u]++;
c[v]++;
if(c[u]==0) cur--;
if(c[v]==0) cur--;
}
if(i!=m-1&&dcmp(l-e[i+1].l)==0) continue;
if(cur>ans)
{
ans=cur;
len=l;
}
}
printf("%d\n",ans);
printf("%.4f\n",len);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: