zoukankan      html  css  js  c++  java
  • 2015编程之美资格赛题目3 : 基站选址 分类: 算法 2015-04-21 15:15 148人阅读 评论(0) 收藏

    描述

    需要在一个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


    刚开始以为是最小代价生成树的问题,其实是个数学问题,求平面上一点到n个点的距离最小。


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <algorithm>
    #include <limits>
    #define MOD 100007
    using namespace std;
    
    int m , n , num_a,num_b, x, y;
    int x1[1001], y1[1001], x2[1001], y2[1001]; 
    long long sum_x, sum_y, ans ,ans_x, ans_y;
    
    void find_ans(int x, int y) {
    	int s = 0, temp = INT_MAX;
    
    	for (int k = 1; k <= num_1; k++)
    		s += (x1[k] - x) * 1LL * (x1[k] - x) + (y1[k] - y) * 1ll * (y1[k] - y);
    	for (int k = 1 ; k <= num_b; k++)
    		temp = min(temp, abs(x2[k]-x) + abs(y2[k]-y)*1LL);
    	if(s+temp <ans) {
    		ans = s+temp;
    	}
    }
    
    
    int main()
    {
        int T,num;
        scanf("%d", &T);
        for ( num = 1; num <= T; num++ )
        {
    		scanf("%d %d %d %d",&m,&n,&num_a,&num_b);
    		sum_x = 0;
    		sum_y = 0;
    		for (int i = 1 ; i <= num_a; i++) {
    			scanf("%d %d", &x1[i], &y1[i]);
    			sum_x += x1[i];
    			sum_y += y1[i];
    		}
    		for (int i = 1 ; i <= num_b; i++)
    			scanf("%d %d", &x2[i], &y2[i]);
    		x = sum_x / num_a;
    		y = sum_y / num_b;
    		ans = INT_MAX;
    		for (int i = x-1; i <= x+1; i++)
    			for (int j = y-1; j <= y+1; j++){
    				if ( i >= 1 && i <= n && j >=1 && j <=m)
    					find_ans(i,j);
    			}
            printf("Case #%d: %d
    ",num,ans);
        }
        return 0;
    }
    






    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    InfoPath开发误区
    error: 80040111
    EasyUi通过POI 实现导出xls表格功能
    webservice入门
    CXF框架入门(重点)
    Spring整合Shiro
    EasyUi通过OCUpload上传及POI上传 实现导入xls表格功能
    Matlab自定义安装
    一位大学教师对学生的建议:如何做好研究
    What is covariate(协变量)
  • 原文地址:https://www.cnblogs.com/learnordie/p/4656931.html
Copyright © 2011-2022 走看看