标签:
题意:给一个网格大小,在其中找一个基站,使得到每个用户之间的距离的平方(欧几里得距离的平方),和到其中任一个通讯的距离(曼哈顿距离)的总距离(代价)最小。其实就是到每个用户的距离最小的基础上,到通讯公司也要尽可能近,距离也就是代价。
思路:一开始觉得需要每个点都尝试,计算代价,再比较代价,找出基站最佳位置。但是,这样还叫算法?不是比穷举更快的算法都不叫算法!那么得想办法减少搜索的点,想到基站不可能建立在一个其某一个方向上完全没有用户或者通讯公司的地方,比如用户和通讯公司都在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 }
编程之美2015 资格赛 hihocoder 题目3 : 基站选址
标签:
原文地址:http://www.cnblogs.com/xcw0754/p/4437107.html