编程之美2015 资格赛 hihocoder 题目3 : 基站选址

题意:给一个网格大小,在其中找一个基站,使得到每个用户之间的距离的平方(欧几里得距离的平方),和到其中任一个通讯的距离(曼哈顿距离)的总距离(代价)最小。其实就是到每个用户的距离最小的基础上,到通讯公司也要尽可能近,距离也就是代价。

思路:一开始觉得需要每个点都尝试,计算代价,再比较代价,找出基站最佳位置。但是,这样还叫算法?不是比穷举更快的算法都不叫算法!那么得想办法减少搜索的点,想到基站不可能建立在一个其某一个方向上完全没有用户或者通讯公司的地方,比如用户和通讯公司都在x坐标10以上,而我们建立在x坐标为1的地方,那么没有意义。所以可以找到用户和通讯公司的x坐标最大和最小,y坐标最大和最小。则小于最小,和大于最大的都不用进行搜索了,而中间的都要进行计算代价。虽然AC了,但是还是有点费时,87ms。感觉应该考虑用户的距离就行了,下午再试试。

 1 #include <iostream>
 2 #include <cmath>
 3 #include <stdio.h>
 4 using namespace std;
 5 int n, m, a, b; //网格n*m     a个用户    b个通讯公司
 6 struct pos
 7 {
 8     int x,y;
 9 }apos[1005],bpos[1005];
10
11 long long compute(int minx, int miny, int maxx, int maxy)
12 {
13     long long minv=99999999;
14     for(int i=minx; i<maxx; i++)
15     {
16         for(int j=miny; j<maxy; j++)
17         {
18             long long tmp=0;
19
20             for(int k=0; k<a; k++)      //到a个用户的代价
21                 tmp +=(i-apos[k].x)*(i-apos[k].x) + (j-apos[k].y)*(j-apos[k].y) ;
22             int v=999999;
23             for(int k=0; k<b; k++)      //到b个公司的最小代价
24                 if( abs(i-bpos[k].x)+abs(j-bpos[k].y) <v )
25                     v =abs(i-bpos[k].x)+abs(j-bpos[k].y);
26
27             if( tmp+v<minv )
28                 minv = tmp + v;
29         }
30     }
31     return minv;
32 }
33
34 int main()
35 {
36
37     //freopen("input.txt", "r", stdin);
38     int t, j=0;
39
40     cin>>t;
41     while(t--)
42     {
43         int minx=999999, miny=999999, maxx=-1, maxy=-1;        //找到a和b中最大的x和y,以及最小的x和y
44         cin>>n>>m>>a>>b;
45         for(int i=0; i<a; i++)  //输入用户位置
46         {
47             cin>>apos[i].x>>apos[i].y;
48             if( apos[i].x<minx )
49                 minx =apos[i].x;
50             if( apos[i].x>maxx )
51                 maxx =apos[i].x;
52             if( apos[i].y<miny )
53                 miny =apos[i].y;
54             if( apos[i].y>maxy )
55                 maxy =apos[i].y;
56         }
57
58         for(int i=0; i<b; i++)  //输入公司位置
59         {
60             cin>>bpos[i].x>>bpos[i].y;
61             if( bpos[i].x<minx )
62                 minx =bpos[i].x;
63             if( bpos[i].x>maxx )
64                 maxx =bpos[i].x;
65             if( bpos[i].y<miny )
66                 miny =bpos[i].y;
67             if( bpos[i].y>maxy )
68                 maxy =bpos[i].y;
69         }
70         cout<<"Case #"<< ++j<<": "<<compute(minx, miny, maxx, maxy)<<endl;
71
72     }
73     return 0;
74 }

基站选址

时间: 2024-08-24 07:41:09

编程之美2015 资格赛 hihocoder 题目3 : 基站选址的相关文章

编程之美2015 资格赛 hihocoder 题目2: 回文字符序列

思路:暴力搜,用BFS的方式,生成每一种可能,再对每一种可能进行判断是否回文,进行统计.严重超时!计算一个25个字符的,大概要20多秒! 1 #include <iostream> 2 #include <deque> 3 #include <string> 4 #include <stdio.h> 5 #include <cstring> 6 using namespace std; 7 8 deque<string> a; 9 1

编程之美2015资格赛

题目1 : 2月29日 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期). 只有闰年有2月29日,满足以下一个条件的年份为闰年: 1. 年份能被4整除但不能被100整除 2. 年份能被400整除 输入 第一行为一个整数T,表示数据组数. 之 后每组数据包含两行.每一行格式为"month day, year",表示一个日期.month为{"January", "Fe

hiho 编程之美2015资格赛(基站选址-绝对值方程分段)[无数据]

题目3 : 基站选址 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 需要在一个N × M的网格中建立一个通讯基站,通讯基站仅必须建立在格点上. 网格中有A个用户,每个用户的通讯代价是用户到基站欧几里得距离的平方. 网格中还有B个通讯公司,维护基站的代价是基站到最近的一个通讯公司的路程(路程定义为曼哈顿距离). 在网格中建立基站的总代价是用户通讯代价的总和加上维护基站的代价,最小总代价. 输入 第一行为一个整数T,表示数据组数. 每组数据第一行为四个整数:N, M,

编程之美2015资格赛:基站选址

题目3 : 基站选址 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 需要在一个N × M的网格中建立一个通讯基站,通讯基站仅必须建立在格点上. 网格中有A个用户,每个用户的通讯代价是用户到基站欧几里得距离的平方. 网格中还有B个通讯公司,维护基站的代价是基站到最近的一个通讯公司的路程(路程定义为曼哈顿距离). 在网格中建立基站的总代价是用户通讯代价的总和加上维护基站的代价,最小总代价. 输入 第一行为一个整数T,表示数据组数. 每组数据第一行为四个整数:N, M,

微软2编程之美2015资格赛

题目1 :2月19日 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期). 只有闰年有2月29日,满足以下一个条件的年份为闰年: 1. 年份能被4整除但不能被100整除 2. 年份能被400整除 输入 第一行为一个整数T,表示数据组数. 之后每组数据包含两行.每一行格式为"month day, year",表示一个日期.month为{"January", "Febr

编程之美2015资格赛 题目1 : 2月29日

时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期). 只有闰年有2月29日,满足以下一个条件的年份为闰年: 1. 年份能被4整除但不能被100整除 2. 年份能被400整除 输入 第一行为一个整数T,表示数据组数. 之后每组数据包含两行.每一行格式为"month day, year",表示一个日期.month为{"January", "February",

编程之美2015资格赛:回文字符序列

题目2 : 回文字符序列 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定字符串,求它的回文子序列个数.回文子序列反转字符顺序后仍然与原序列相同.例如字符串aba中,回文子序列为"a", "a", "aa", "b", "aba",共5个.内容相同位置不同的子序列算不同的子序列. 输入 第一行一个整数T,表示数据组数.之后是T组数据,每组数据为一行字符串. 输出 对于每组数据

编程之美2015资格赛A题

题目1 : 2月29日 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期). 只有闰年有2月29日,满足以下一个条件的年份为闰年: 1. 年份能被4整除但不能被100整除 2. 年份能被400整除 输入 第一行为一个整数T,表示数据组数. 之 后每组数据包含两行.每一行格式为"month day, year",表示一个日期.month为{"January", "Fe

hiho 编程之美2015资格赛(2月29日-模拟日期)

题目1 : 2月29日 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期). 只有闰年有2月29日,满足以下一个条件的年份为闰年: 1. 年份能被4整除但不能被100整除 2. 年份能被400整除 输入 第一行为一个整数T,表示数据组数. 之后每组数据包含两行.每一行格式为"month day, year",表示一个日期.month为{"January", "Feb