https://vjudge.net/problem/UVALive-2963
题意:
需要在n个星球上各装一个广播装置,作用范围均为R。每个星球广播A类节目或者B类节目。a表示星球i收听到的和自己广播相同节目的星球数(包括星球i自己),b表示不想同,如果a<b,说明星球是不稳定的,现在要选择尽量小的R,使得不稳定的星球尽量多些。
思路:
先把所有点之间的距离计算出来并排好序。
接下来我们就按照边长来依次扫描,每次根据扫描的信息动态维护每个星球的稳定情况。
需要注意的是处理好边长相同的情况。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<stack> 7 #include<queue> 8 #include<cmath> 9 #include<map> 10 using namespace std; 11 typedef long long LL; 12 typedef pair<int,int> pll; 13 const int INF=0x3f3f3f3f; 14 const int maxn=1000+5; 15 16 int n; 17 int num[maxn]; 18 19 struct Point 20 { 21 int x,y,z,p; 22 }a[maxn]; 23 24 struct Edge 25 { 26 int x,y; 27 double d; 28 bool operator<(const Edge& rhs) const 29 { 30 return d<rhs.d; 31 } 32 }e[maxn*maxn]; 33 34 double cacl(int i,int j) 35 { 36 int x=a[i].x-a[j].x,y=a[i].y-a[j].y,z=a[i].z-a[j].z; 37 return sqrt((double)x*x+(double)y*y+(double)z*z); 38 } 39 40 int main() 41 { 42 //freopen("D:\input.txt","r",stdin); 43 while(~scanf("%d",&n)) 44 { 45 for(int i=1;i<=n;i++) 46 { 47 scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].z,&a[i].p); 48 num[i]=1; 49 } 50 51 int cnt=0; 52 for(int i=1;i<=n;i++) 53 for(int j=i+1;j<=n;j++) 54 { 55 e[cnt].x=i; 56 e[cnt].y=j; 57 e[cnt].d=cacl(i,j); 58 cnt++; 59 } 60 61 int temp=0; 62 int ans=0; 63 double length=0; 64 sort(e,e+cnt); 65 for(int i=0;i<cnt;i++) 66 { 67 int u=e[i].x,v=e[i].y; 68 if(a[u].p!=a[v].p) 69 { 70 num[u]--; 71 num[v]--; 72 if(num[u]==-1) temp++; //如果=-1,则由稳定变成了不稳定 73 if(num[v]==-1) temp++; 74 } 75 else 76 { 77 num[u]++; 78 num[v]++; 79 if(num[u]==0) temp--; 80 if(num[v]==0) temp--; 81 } 82 83 if(i!=cnt-1 && e[i].d==e[i+1].d) continue; //处理距离相等的边 84 if(ans<temp) 85 { 86 ans=temp; 87 length=e[i].d; 88 } 89 } 90 printf("%d %.4f ",ans,length); 91 } 92 return 0; 93 }