UVALive 2963 Hypertransmission

来源:互联网 发布:linux流量监控工具 编辑:程序博客网 时间:2024/06/05 20:29

题目链接:https://vjudge.net/problem/UVALive-2963

题目大意:有n个星球,每个星球坐标为(xi,yi,zi),可以看成一个点。每个星球广播A类节目或B类节目,广播范围为R(以该星球为中心半径为R的球体)。令N+(i)表示星球i听到的和自己广播相同节目的星球数(包括自己),N-(i)表示星球i听到的和自己广播不同节目的星球数。如果N+(i)<N-(i),则称星球i是不稳定的。求不稳定星球的最大数目以及在此前提下R的最小值。

思路:容易知道,R的值肯定为某两个星球之间的距离。因此将所有距离从小到大排序,并存储每个距离所对应的两个点。按顺序枚举每个距离,根据这些距离所对应的点更新N+(i)和N-(i)即可。又因为半径大的球会包含半径小的球,所以前面的结果可以适用于后面。


#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <cctype>#include <cstdlib>#include <map>#include <iostream>#include <queue>using namespace std;typedef long long LL;const int dr[] = {0,0,-1,1};const int dc[] = {-1,1,0,0};const int maxn = 1000 + 10;struct Point{   int x, y, z, t;}p[maxn];struct Triple{int d, pa, pb;bool operator < (const Triple& rhs) const {return d < rhs.d;}bool operator == (const Triple &rhs) const {return d == rhs.d;}Triple(int d = 0, int pa = 0, int pb = 0) : d(d),pa(pa),pb(pb){}}tri[maxn*maxn];int dist(const Point& A, const Point& B){return (A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y) + (A.z-B.z)*(A.z-B.z);}int vis[maxn];int main(){int n;while(scanf("%d", &n) == 1){for(int i = 0; i < n; i++) scanf("%d%d%d%d", &p[i].x, &p[i].y, &p[i].z, &p[i].t);int cnt = 0;    for(int i = 0; i < n; i++)       for(int j = i+1; j < n; j++)         tri[cnt++] = Triple(dist(p[i],p[j]), i, j);    sort(tri, tri+cnt);        fill(vis, vis+n+2, 1);        int temp = 0, ans = 0, R = 0, j;        for(int i = 0; i < cnt;) {           for(j = i; j < cnt && tri[j].d == tri[i].d; j++)           {             int ta = tri[j].pa, tb = tri[j].pb;             if(p[ta].t != p[tb].t)             {              if(--vis[ta] == -1) temp++;              if(--vis[tb] == -1) temp++;             }             else {              if(++vis[ta] == 0) temp--;              if(++vis[tb] == 0) temp--;             }           }           if(temp > ans) {             ans = temp;             R = tri[i].d;           }           i = j;        }        printf("%d\n%.4f\n", ans, sqrt(R*1.0));}return 0;}