题目描述:
某小区决定在小区内部建一家便利店,现小区内部共有八栋楼,它们的地理坐标分别为:(10,20) (30,34) (19,25) (38,49.1) (9,38.1) (2,34) (5,8) (29,48)。同时,其中的住户人数分别为:30, 45, 28, 8, 36, 16, 78, 56。为了方便更多的住户购物,要求实现总体最优,请问便利店应该建立在哪里?
【提示】
1)便利店无论选址何处,八栋楼的居民均可直接到达,即八栋楼与便利店均相邻,且距离为直线距离;
2)八栋楼的居民人数为权重,应该方便大多数人,实现总体最优。
感觉好玩的数据结构课程设计题,虽然没发现这题跟数据结构有什么关系。看到这题想了好久没什么思路,没发现什么数据结构可以解这题。枚举点的话,也没有什么好的策略(其实也蛮麻烦)。前几天打了一场warmup,有道题比赛的时候想了好久的,一直以为是搜索,但是数据量太大也没敢写。比赛完了发现那题竟然是用随机算法过的。瞬间感觉随机算法好强大的样子。然后就想到了这题,随机算法太适合不过了。与其苦苦想枚举点的策略,还不如随机打10w个点呢,10w不够?1000w如何?
详情请见代码:
#include <iostream> #include<cstdio> #include<cstring> #include<ctime> #include<cmath> using namespace std; const int N = 100; const double inf = 10000000.0; const double eps = 1e-8; int people_num[N]; struct node { double x,y; }position[N]; int n; double dis(int i,double x,double y) { return sqrt((x - position[i].x) * (x - position[i].x) + (y - position[i].y) * (y - position[i].y)); } double cal(double x,double y) { double ret = 0; for(int i = 1;i <= n;i ++) ret = ret + dis(i,x,y) * people_num[i]; return ret; } int main() { int i; freopen("data.in","r",stdin); scanf("%d",&n); double minx,miny,maxy,maxx; minx = miny = inf; maxx = maxy = -inf; for(i = 1;i <= n;i ++) { scanf("%lf%lf",&position[i].x,&position[i].y); if(position[i].x > maxx) maxx = position[i].x; if(position[i].x < minx) minx = position[i].x; if(position[i].y > maxy) maxy = position[i].y; if(position[i].y < miny) miny = position[i].y; } for(i = 1;i <= n;i ++) scanf("%d",&people_num[i]); maxx *= 100; maxy *= 100; minx *= 100; miny *= 100; int lenx = ceil(maxx - minx); int leny = ceil(maxy - miny); double ansx,ansy,Max; Max = inf; srand((unsigned)time(NULL)); for(i = 1;i <= 100000;i ++) { double tmpx = rand()%lenx + minx; double tmpy = rand()%leny + miny; tmpx = tmpx / 100; tmpy = tmpy / 100; double tmp = cal(tmpx,tmpy); if(tmp - Max < eps) { ansx = tmpx; ansy = tmpy; Max = tmp; } } printf("便利店的地址为:(%.2lf,%.2lf) ",ansx,ansy); return 0; } /* 便利店地址:(16.53,27.43) 最优值:5146.85 */
随机算法,你值得拥有哟嚯嚯嚯嚯~