1325 - Hypertransmission
Time limit: 6.000 secondsThe president of the Galactic Federation has recently decided that all planets of the galaxy must establishhyper-radio centers to broadcast their programs. To ensure the process, the government has signed the contractwith well known hyper-radio equipment manufacturer Trojan Horse Ltd. By the terms of this contract the companyhas 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 eachplanet of the galaxy one of these movements has the majority. It is clear that after establishing thehyper-radio station on the planet, the political programs of the station will support the movement thathas the majority on this planet.
All transmitters supplied by Trojan Horse Ltd will have the same range, so hyper-radio programs from eachplanet will be heard at the distance not exceedingR parsecs from it. Since the company director is actuallythe agent of the Dark Empire, he wants to chooseR in such a way, that it would destabilize the politicalsituation in the Galactic Federation.
More precisely, for each planet A let N+(A) be the number of planets where the same political movementas inA has the majority and hyper-radio programs fromA are received, including A itself. Similarly,letN-(A) be the number of planets where the other political movement has the majority and hyper-radioprograms fromA are received. The planet A is called destabilizing if N+(A) < N-(A).
Your task is to choose such R that the numberD of destabilizing planets is maximal possible. Sinceincreasing transmitter's range requires more resources for its manufacturing, you must find the smallestpossibleR maximizing D.
Input
Input consists of several datasets. The first line of each dataset contains N - the number of planets in the Galactic Federation (1N
1000).NextN lines contain four integer numbers xi, yi, zi, and pi each and describe the planets:xi,yi, and zi specify the coordinates of the planet in space,pi = 0 if the industrialistshave the majority on the planet andpi = 1 if the ecologists have the majority. All coordinates do notexceed 10 000 by their absolute value. No two planets occupy the same point.
Output
First output D - the maximal possible number of destabilizing planets. After that output non-negative realnumberR - the minimal range that hyper-radio transmitters must have so that the number of destabilizingplanets isD. R must be accurate within10-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
解题报告:题意略复杂。差不多是这样的,整个星系有2个党派,各自控制一些星球。现在每个星球有自己的广播系统,广播半径都是 r 。如果某个星球收到的自己党派的广播数小于收到的对手党派的广播数,那么这个星球就是不和谐的。现在让我们求出最小的半径,让不和谐的星球数最多。
虽然也是最小的最大值问题,但是由于问题不是单调的,不是说半径越大不和谐的星球就越多,所以不能二分来求。
星球数1000个,我们可以枚举每两个星球间的距离。对于每个星球,可能会有从和谐星球突变为不和谐星球的距离,以及从不和谐星球突变为和谐星球的距离。我们把这些距离统计起来,从小到大排列,扫描一遍,更新不和谐星球最大值即可。代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <string>
using namespace std;
#define ff(i, n) for(int i=0;i<(n);i++)
#define fff(i, n, m) for(int i=(n);i<=(m);i++)
#define dff(i, n, m) for(int i=(n);i>=(m);i--)
#define mem(a) memset((a), 0, sizeof(a))
typedef long long LL;
typedef unsigned long long ULL;
void work();
int main()
{
#ifdef ACM
freopen("in.txt", "r", stdin);
// freopen("in.txt", "w", stdout);
#endif // ACM
work();
}
/*****************************************/
struct Planet
{
double x, y, z;
int type;
} planet[1111];
double dd[1111];
int n;
bool cmp(double a, double b)
{
return abs(a) < abs(b);
}
double dis(Planet & a, Planet & 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) );
}
void work()
{
while(~scanf("%d", &n))
{
ff(i, n) scanf("%lf%lf%lf%d", &planet[i].x, &planet[i].y, &planet[i].z, &planet[i].type);
map<double, int> event;
ff(i, n)
{
int tot = 0;
ff(j, n)
{
double d = dis(planet[i], planet[j]);
if(planet[i].type != planet[j].type) d = -d;
dd[tot++] = d;
}
sort(dd, dd+tot, cmp);
int cnt = 0;
ff(j, tot)
{
if(dd[j] >= 0)
{
cnt++;
if(cnt == 0) event[dd[j]]--;
}
else
{
cnt--;
if(cnt == -1) event[-dd[j]]++;
}
}
}
int ans = 0;
int cnt = 0;
double r = 0;
for(map<double, int>::iterator it = event.begin(); it != event.end(); it++)
{
cnt += it->second;
if(ans < cnt)
{
ans = cnt;
r = it->first;
}
}
printf("%d\n%lf\n", ans, r);
}
}