【编程之美】题目3:基站选址

source:http://hihocoder.com/contest/msbop2015qual/problem/3

描述

需要在一个N × M的网格中建立一个通讯基站,通讯基站仅必须建立在格点上。

网格中有A个用户,每个用户的通讯代价是用户到基站欧几里得距离的平方。

网格中还有B个通讯公司,维护基站的代价是基站到最近的一个通讯公司的路程(路程定义为曼哈顿距离)。

在网格中建立基站的总代价是用户通讯代价的总和加上维护基站的代价,最小总代价。

输入

第一行为一个整数T,表示数据组数。

每组数据第一行为四个整数:N, M, A, B。

接下来的A+B行每行两个整数x, y,代表一个坐标,前A行表示各用户的坐标,后B行表示各通讯公司的坐标。

输出

对于每组数据输出一行"Case #X: Y",X代表数据编号(从1开始),Y代表所求最小代价。

数据范围

1 ≤ T ≤ 20

1 ≤ x ≤ N

1 ≤ y ≤ M

1 ≤ B ≤ 100

小数据

1 ≤ N, M ≤ 100

1 ≤ A ≤ 100

大数据

1 ≤ N, M ≤ 107

1 ≤ A ≤ 1000

样例输入

2
3 3 4 1
1 2
2 1
2 3
3 2
2 2
4 4 4 2
1 2
2 4
3 1
4 3
1 4
1 3

样例输出

Case #1: 4
Case #2: 13

解体思路:类似于建邮局问题,转换为平均数。
#include 
#include 
#include 
#include 
//#include 
using namespace std;

const int XX[4]={0,0,1,1};
const int YY[4]={0,1,0,1};

int main(){
    //ifstream cin("2.txt");
    int T;
    cin >> T;
    for(int icase = 1; icase <= T; ++ icase){
        long long N,M,A,B;
        cin >>N>>M>>A>>B;
        vector<long long> a_x(A,0), a_y(A,0);
        vector<long long> b_x(B,0), b_y(B,0);
        for(int i = 0 ; i  < A; ++ i )
            cin >> a_x[i]>>a_y[i];
        for(int i = 0 ; i <  B; ++ i)
            cin >> b_x[i] >> b_y[i];
        long long sum_a_x_2 = 0, sum_a_x = 0, sum_a_y = 0, sum_a_y_2 = 0;
        for(int i = 0 ; i < A ; ++ i){
            sum_a_x_2+=a_x[i]*a_x[i];
            sum_a_x +=a_x[i];

            sum_a_y +=a_y[i];
            sum_a_y_2+=a_y[i]*a_y[i];
        }
        long long x = sum_a_x/A, y=sum_a_y/A, ans = LLONG_MAX;
        for(int i = 0 ; i < 4; ++ i){
            long long curx = x + XX[i], cury = y+YY[i],total_dis = LLONG_MAX;
            long long curResult = sum_a_x_2 + A*curx*curx-2*curx*sum_a_x + sum_a_y_2 + A*cury*cury - 2*cury*sum_a_y;
            for(int j = 0 ; j < B; ++ j){
                total_dis = min(total_dis,abs(curx-b_x[j])+abs(cury-b_y[j]));
            }
            ans = min(ans,curResult+total_dis);
        }
        cout<<"Case #"<": "<endl;
    }
}
 
   

 

 

转载于:https://www.cnblogs.com/zxy1992/p/4439741.html

你可能感兴趣的:(大数据)