思路:有两种方法:(1)二分枚举答案,(2)排序,然后直接扫描,这里有个小技巧,就是每个节点都保存距离比它小的节点的人数之和,这样可以在降低第二步处理的时间复杂度,总是间复杂度为O(nlogn)+O(n) = O(nlogn)。两种方法运行时间一样,一开始我是直接二分的,做完后看题目标签是sort,然后感觉排序可做,就写了一下。
二分版:
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 1010
using namespace std;
const double eps = 1e-8;
typedef struct Point{
int x, y, man;
double dist;
void d(){
dist = sqrt(x*x+y*y);
}
}Point;
Point P[MAXN];
int n, s;
int Judge(double len){
int sum = 0;
for(int i = 0;i < n;i ++){
if(P[i].dist + eps < len) sum += P[i].man;
if(sum + s >= 1000000) return 1;
}
return -1;
}
double binary_Search(double l, double r){
double ll, rr, mid;
ll = l, rr = r;
while(ll < rr+eps){
mid = (ll + rr)/2;
int flag = Judge(mid);
if(flag == 1) rr = mid-eps;
else if(flag == -1) ll = mid+eps;
}
return ll;
}
int main(){
double maxn;
/* freopen("in.c", "r", stdin); */
/* freopen("out.cpp" , "w", stdout); */
while(~scanf("%d%d", &n, &s)){
int sum = 0;
maxn = eps;
for(int i = 0;i < n;i ++){
scanf("%d%d%d", &P[i].x, &P[i].y, &P[i].man);
P[i].d();
sum += P[i].man;
maxn = max(maxn, P[i].dist);
}
if(sum + s < 1000000) printf("-1\n");
else if(sum + s == 1000000) printf("%.8lf\n", maxn);
else printf("%.8lf\n", binary_Search(eps, maxn));
}
return 0;
}
sort版:
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 1010
const double eps = 1e-8;
using namespace std;
typedef struct Point{
int x, y, man, sum;
double dist;
void d(){
dist = sqrt(x*x+y*y);
}
bool operator < (const Point &A) const{
return dist < A.dist;
}
}Point;
Point P[MAXN];
int main(){
int n, s;
/* freopen("in.c", "r", stdin); */
while(~scanf("%d%d", &n, &s)){
int sum = 0;
double maxn = eps;
for(int i = 0;i < n;i ++){
scanf("%d%d%d", &P[i].x, &P[i].y, &P[i].man);
P[i].d();
maxn = max(maxn, P[i].dist);
sum += P[i].man;
P[i].sum = P[i].man;
}
if(sum + s < 1000000) printf("-1\n");
else if(sum + s == 1000000) printf("%.8lf\n", maxn);
else{
sort(P, P+n);
for(int i = 0;i < n;i ++){
if(P[i].sum + s >= 1000000){
printf("%.8lf\n", P[i].dist);
break;
}
P[i+1].sum += P[i].sum; //注意这点;
}
}
}
}