LA 2963 超级传输(扫描)

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\n%.4f\n",ans,length);
91     }
92     return 0;
93 }

 

转载于:https://www.cnblogs.com/zyb993963526/p/6919079.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值