UVALive 2963 Hypertransmission

2963 - Hypertransmission

Time limit: 6.000 seconds

Description

The president of the Galactic Federation has recently decided that all planets of the galaxy must establish hyper-radio centers to broadcast their programs. To ensure the process, the government has signed the contract with well known hyper-radio equipment manufacturer Trojan Horse Ltd. By the terms of this contract the company has to provide N hypertransmitters, one for each planet of the Federation.

It is known that there are two main political movements in the galaxy: industrialism and ecologism. On each planet of the galaxy one of these movements has the majority. It is clear that after establishing the hyper-radio station on the planet, the political programs of the station will support the movement that has the majority on this planet.

All transmitters supplied by Trojan Horse Ltd will have the same range, so hyper-radio programs from each planet will be heard at the distance not exceeding R parsecs from it. Since the company director is actually the agent of the Dark Empire, he wants to choose R in such a way, that it would destabilize the political situation in the Galactic Federation.

More precisely, for each planet A let N+(A) be the number of planets where the same political movement as inA has the majority and hyper-radio programs from A are received, including A itself. Similarly, let N-(A) be the number of planets where the other political movement has the majority and hyper-radio programs from A are received. The planet A is called destabilizing if N+(A) < N-(A).

Your task is to choose such R that the number D of destabilizing planets is maximal possible. Since increasing transmitter's range requires more resources for its manufacturing, you must find the smallest possible R maximizing D.


Input 

Input consists of several datasets. The first line of each dataset contains N - the number of planets in the Galactic Federation (1$ \le$N$ \le$1000). Next N lines contain four integer numbers xiyizi, and pi each and describe the planets: xiyi, and zi specify the coordinates of the planet in space, pi = 0 if the industrialists have the majority on the planet and pi = 1 if the ecologists have the majority. All coordinates do not exceed 10 000 by their absolute value. No two planets occupy the same point.

Ouput

First output D - the maximal possible number of destabilizing planets. After that output non-negative real number R - the minimal range that hyper-radio transmitters must have so that the number of destabilizing planets is DR must be accurate within 10-4 of the correct answer.


Sample Input

4
0 0 0 1
0 1 0 0
1 0 0 0
1 1 0 1


Sample Output 

4
1.0000

题意:每个星球都要造一座广播台,广播台主要有两种,让你选择一个距离d, 以每一个星球为圆心,以d为半径,圆范围内,跟它型号相同的星球数量记为N+(A),包括自己本身,跟它型号不同的记为N-(A), 如果一个星球的N+(A) < N-(A) , 那么这个星球就标记为不稳定的,现在问你最多能使多少个星球为不稳定,并且使d尽可能的小。

思路:很明显的一道dp,因为d肯定是其中两点之间的距离,所以我们可以先算出每两点之间的距离,用一个结构体保存每条边的两个端点和长度,为了节省时间,把这些边从小到大排序,相同的长度的边就可以一起处理。用val[]数组来记录N+(A)和N-(A)的数量,因为N+(A)是要包括自己本身的,所以我们在初始化的时候都把它标记为1,遇到型号相同的就+1,遇到不同的就-1,当val值为负就代表不稳定,为正就为稳定,为了避免重复计算,就规定为-1时为不稳定,为0时为稳定。

代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1010;
int n, val[N];
struct node
{
	int x,y,z;
	int type;
}p[N];

struct Node
{
	int s, t;
	int dis;
	bool operator<(const Node &r) const {
		return dis < r.dis;
	}
}q[N*N/2];

int fd(node a, node 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 main()
{
	int i, j;
	while(~scanf("%d", &n))
	{
		for(i = 0; i < n; i ++)
		{
			scanf("%d%d%d%d", &p[i].x, &p[i].y, &p[i].z, &p[i].type);
		}
		int tmp = 0;
		for(i = 0; i < n; i ++)
		{
			val[i] = 1;
			for(j = i + 1; j < n; j ++)
			{
				q[tmp].s = i;
				q[tmp].t = j;
				q[tmp].dis = fd(p[i], p[j]);
				tmp ++;
			}	
		}
		sort(q, q + tmp); 
		int cnt, ans, d;
		cnt = ans = d = 0;
		for(i = 0; i < tmp; )
		{
			for(j = i; j < tmp && q[j].dis == q[i].dis; j ++)
			{
				if(p[q[j].s].type != p[q[j].t].type)
				{
					if(-- val[q[j].s] == -1)  
                    	cnt++;  
                    if(-- val[q[j].t] == -1)  
                        cnt++;
				}
				else 
				{  
                    if(++ val[q[j].s] == 0)  
                        cnt --;  
                    if(++ val[q[j].t] == 0)  
                        cnt --;  
                }  
			}
			if(cnt > ans)
			{  
                ans = cnt;  
                d = q[i].dis;  
            }  
            i = j;
		}
		printf("%d\n%.4lf\n", ans, sqrt(d*1.0));
	}
	return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值