UVALive 2963/ UVA1325 – Hypertransmission(扫描)

题目链接:UVA1325

【题意】要在n个星球上各装一个广播装置,作用范围均为R(即和它距离不超过R的星球能收听到它的广播)。每个星球广播A类节目或者B类节目。另N+(i)表示星球i能收听到的和自己广播相同节目的星球数量(包括星球i自己),N-(i)表示星球i收听到广播另一种节目的星球数。如果N+(i)<N-(i),我们就说星球i是不稳定的。你是暗黑世界的间谍,因此希望选择R,使得不稳定的星球尽量多。在此前提下,R应尽量小。

【分析】需要用扫描的思想,直接暴力肯定超时的,首先可以知道最大不稳定的星球数量肯定在r的值为某两个星球的距离,这样先枚举出所有星球之间的距离,这样已经是O(N^2)复杂度了,对于1000的N来说基本上只能线性扫描了;还可以发现只要把距离从小到大排序,以前小的距离计算过的每个星球的稳定值na(就是[n+(i)] – [n-(i)]的值)可以被大的距离所利用,每次改变的na其实只是距离为当前r的所有两两对应的星球,这样只要两个星球为同一频段那就把两个星球的na都+1,反之-1,这样每次当-++na == 0时说明这个星球刚好从不稳定变成稳定,–na==-1时改星球从稳定变成不稳定;最后需要注意把所有距离相等的要都算完后再更新ans,还有所有星球都是同一频段的时候r为0、

【AC CODE】343ms

 

#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <set>
//#include <unordered_map>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
typedef long long LL;
#define rep(i,a,n) for(int i = a; i < n; i++)
#define repe(i,a,n) for(int i = a; i <= n; i++)
#define per(i,n,a) for(int i = n; i >= a; i--)
#define clc(a,b) memset(a,b,sizeof(a))
const int INF = 0x3f3f3f3f, MAXN = 1000 + 10;
struct NODE{
	int x, y, z, type;
}p[MAXN];
struct S{
	int u, v, dis;
	bool operator<(const S&t)const{
		return dis < t.dis;
	}
}s[MAXN*MAXN];
int na[MAXN];//na+和na-的差,na<0时表示星球不稳定

inline int get_dis(int a, int b)
{
	return (p[a].x - p[b].x)*(p[a].x - p[b].x) + (p[a].y - p[b].y)*(p[a].y - p[b].y) + (p[a].z - p[b].z)*(p[a].z - p[b].z);
}
int main()
{
#ifdef SHY
	freopen("d:\\1.txt", "r", stdin);
#endif
	int n;
	while (~scanf("%d%*c", &n))
	{
		rep(i, 0, n) scanf("%d %d %d %d%*c", &p[i].x, &p[i].y, &p[i].z, &p[i].type);
		int cnt = 0;
		rep(i, 0, n)
		{
			na[i] = 1;
			rep(j, i + 1, n)
				s[cnt++] = { i, j, get_dis(i, j) };
		}
		sort(s, s + cnt);
		int ans = 0, tmp = 0, r = 0;
		rep(i, 0, cnt)
		{
			int u = s[i].u, v = s[i].v;
			if (p[u].type == p[v].type)
			{
				if (++na[u] == 0) tmp--;
				if (++na[v] == 0) tmp--;
			}
			else
			{
				if (--na[u] == -1) tmp++;
				if (--na[v] == -1) tmp++;
			}
			if (i != cnt - 1 && s[i].dis == s[i + 1].dis) continue;
			if (tmp > ans)
			{
				ans = tmp;
				r = s[i].dis;
			}
		}
		printf("%d\n%.4f\n", ans, sqrt((double)r));
	}
	return 0;
}

 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

请输入正确的验证码