• 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;
    }
    






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

  • 相关阅读:
    sql 生成javabean实体
    git 安装 使用过程遇到的问题
    CentOS7 ab压力测试安装
    Lvs+keepalived+mysql(主从复制)
    liunx下tomcat启动 Cannot find ./catalina.sh
    ftp和ssh登录缓慢的解决办法
    Contos7 FTP 安装步骤
    python生成100以内格式化的数
    Windows中更新python模块的命令
    scrapy的User-Agent中间件、代理IP中间件、cookies设置、多个爬虫自定义settings设置
  • 原文地址:https://www.cnblogs.com/learnordie/p/4656931.html
Copyright © 2020-2023  润新知