• 【编程之美】题目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;
        }
    }
    
    
    
     
  • 相关阅读:
    启动dubbo服务时报 qosserver can not bind localhost:22222 异常处理
    PostSharp学习
    为什么需要经验丰富的程序员
    商品入库及加入购物车简易流程
    python 中enumerate函数(千年虫)
    将两个列表转成集合(星座性格特点匹配)
    nginx入门手册
    迟来的2021总结
    selenium chrome正在受到自动测试软件的控制
    selenium 上传文件
  • 原文地址:https://www.cnblogs.com/zxy1992/p/4439741.html
Copyright © 2020-2023  润新知