题目大意:有n颗星球,每个星球上都有一个广播,广播的半径为R,广播只能广播两类节目,A类和B类,设N+代表该星球收听到的和自己广播相同节目的星球数,N-表示该星球收听到和自己广播不相同节目的星球数,如果N->N+就表示该星球不稳定,现在要求你设置R,使得不稳定的星球尽量多,在此前提下R最小
解题思路:R肯定是两颗星球之间的距离,这样的话就从小到大枚举星球的半径,找到符合该条件
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#define maxn 1010
using namespace std;
int n;
struct Plant{
double x, y, z;
int play, same, diff;
}p[maxn];
struct Dis{
int a, b;
double dis;
}d[maxn*maxn];
double dis(const Plant a, const Plant b) {
return sqrt((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 cmp(const Dis a, const Dis b) {
return a.dis < b.dis;
}
void solve() {
int cnt = 0;
for(int i = 0; i < n; i++)
for(int j = i + 1; j < n; j++) {
d[cnt].a = i; d[cnt].b = j; d[cnt++].dis = dis(p[i],p[j]);
}
sort(d,d+cnt,cmp);
int ans_num = 0, Diff = 0;
double ans_p = 0;
set<double> s;
for(int i = 0; i < cnt; i++) {
int a = d[i].a, b = d[i].b;
if(p[a].play == p[b].play) {
if(p[a].diff - p[a].same == 1)
Diff--;
if(p[b].diff - p[b].same == 1)
Diff--;
p[a].same++;p[b].same++;
}
if(p[a].play != p[b].play) {
if(p[a].diff == p[a].same)
Diff++;
if(p[b].diff == p[b].same)
Diff++;
p[a].diff++;p[b].diff++;
}
if(i != cnt - 1 && fabs(d[i].dis-d[i+1].dis) < 1e-10)
continue;
if(Diff > ans_num) {
ans_num = Diff;
ans_p = d[i].dis;
}
}
printf("%d\n%.4lf\n",ans_num, ans_p);
}
int main() {
while(scanf("%d",&n) == 1 ) {
for(int i = 0; i < n; i++) {
scanf("%lf%lf%lf%d",&p[i].x, &p[i].y, &p[i].z, &p[i].play);
p[i].same = 1; p[i].diff = 0;
}
solve();
}
return 0;
}