zoukankan      html  css  js  c++  java
  • 【编程之美】题目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 <iostream>
    #include <vector>
    #include <algorithm>
    #include <climits>
    //#include <fstream>
    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 #"<<icase<<": "<<ans<<endl;
        }
    }
    
    
    
     
  • 相关阅读:
    支付方法及注意事项
    网站负载均衡策略
    工作成长
    java内存机制
    关于前途的一些思考
    git记录
    关于博客
    如何为公司创造价值?
    遍历集合方法总结
    二叉树和红黑二叉树
  • 原文地址:https://www.cnblogs.com/zxy1992/p/4439741.html
Copyright © 2011-2022 走看看