[问题描述]

某小区决定在小区内部建一家便利店,现小区内部共有八栋楼,它们的地理坐标分别为:(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)八栋楼的居民人数为权重,应该方便大多数人,实现总体最优。

先是暴力找点的方法。

解题思路:自己开始想的就是暴力枚举,先找大范围,再找小范围。做这个题目就想到了的warmup2的1002题,但当时就是A不了。思路很简单,一步步地精确范围。先把整个地方划分成10*10的方格,再在里面找哪个最小,然后继续10*10每次都这样划分,精度确定跳出循环即可。详解见代码。

代码:

#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<ctime>
using namespace std;
int n; //n栋楼
double minx,miny,maxx,maxy,px,py;  //找到四个边界
double ansx,ansy,sum;  //最后的结果
struct mq
{double x;double y;int peo;
};
mq node[1005];double cal(double px,double py)  //计算值
{int i;double sum=0;for(i=0;i<n;i++)sum+=sqrt((px-node[i].x)*(px-node[i].x)+(py-node[i].y)*(py-node[i].y))*node[i].peo;return sum;
}void solve()
{double i,j;double fenx=maxx-minx;  //把x分成若干份double feny=maxy-miny;  //把y分成若干份while(fenx>0.01&&feny>0.01)  //暴力找点{fenx/=10.0,feny/=10.0;for(i=minx;i<=maxx;i+=fenx)for(j=miny;j<=maxy;j+=feny){double tmp=cal(i,j);if(tmp<sum){sum=tmp;ansx=i;ansy=j;}}minx=ansx-fenx;miny=ansy-feny;maxx=ansx+fenx;maxy=ansy+feny;}
}int main()
{int i;//freopen("input.txt","r",stdin);//freopen("output.txt","w",stdout);while(~scanf("%d",&n))  //n栋楼{scanf("%lf%lf%d",&node[0].x,&node[0].y,&node[0].peo);minx=maxx=node[0].x; miny=maxy=node[0].y;//找到四个边界for(i=1;i<n;i++){scanf("%lf%lf%d",&node[i].x,&node[i].y,&node[i].peo);if(node[i].x<minx) minx=node[i].x;if(node[i].x>maxx) maxx=node[i].x;if(node[i].y<miny) miny=node[i].y;if(node[i].y>maxy) maxy=node[i].y;}sum=100000000;solve();cout<<"便利店选址坐标为:"<<endl;cout<<"x: "<<ansx<<"   "<<"y: "<<ansy<<endl;cout<<"最优解为: "<<sum<<endl;}return 0;
}/*
8
10 20 30
30 34 45
19 25 28
38 49.1 8
9 38.1 36
2 34 16
5 8 78
29 48 56
便利店选址坐标为:
x: 16.5404   y: 27.4362
最优解为: 5146.85
*/

然后就是LCM说的随机算法,也没想到那一块,被他一说是有些道理,但是点的范围一扩大的话,就没那么准确了。

随机算法,我是直接采用的随机数然后%lenth,区间宽度,相当于0~lenth-1。随机函数对范围要求比较严格吧,范围如果太大,随机也没用了。具体实现见代码:

代码:

#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<ctime>
using namespace std;
int n; //n栋楼
struct mq
{double x;double y;int peo;
};
mq node[1005];double cal(double px,double py)  //计算值
{int i;double sum=0;for(i=0;i<n;i++)sum+=sqrt((px-node[i].x)*(px-node[i].x)+(py-node[i].y)*(py-node[i].y))*node[i].peo;return sum;
}
int main()
{int i;freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);double minx,miny,maxx,maxy,px,py;  //找到四个边界double ansx,ansy;  //最后的结果while(~scanf("%d",&n))  //n栋楼{scanf("%lf%lf%d",&node[0].x,&node[0].y,&node[0].peo);minx=maxx=node[0].x; miny=maxy=node[0].y;//找到四个边界for(i=1;i<n;i++){scanf("%lf%lf%d",&node[i].x,&node[i].y,&node[i].peo);if(node[i].x<minx) minx=node[i].x;if(node[i].x>maxx) maxx=node[i].x;if(node[i].y<miny) miny=node[i].y;if(node[i].y>maxy) maxy=node[i].y;}minx*=100,maxx*=100,miny*=100,maxy*=100;  //边界扩大一百倍//找到边界了就可以随机了int lenx,leny;lenx=ceil(maxx-minx),leny=ceil(maxy-miny);double sum=1000000000;srand((unsigned)time(NULL));  //播种for(i=1;i<=500000;i++) //随机50W次{px=rand()%lenx+minx;py=rand()%leny+miny;px/=100.0;py/=100.0;double tmp=cal(px,py);if(tmp<sum){sum=tmp;ansx=px;ansy=py;}}cout<<"便利店选址坐标为:"<<endl;cout<<"x: "<<ansx<<"   "<<"y: "<<ansy<<endl;cout<<"最优解为: "<<sum<<endl;}return 0;
}/*
8
10 20 30
30 34 45
19 25 28
38 49.1 8
9 38.1 36
2 34 16
5 8 78
29 48 56
便利店选址坐标为:
x: 16.56   y: 27.44
最优解为: 5146.85
*/

然后是gcz在我们班群里面说的三分的方法,这个三分很久都没写过了,这个也是二维的三分。二分是解决单调性不变的函数,而三分则是解决类似抛物线这样的函数,有一个凸点或凹点。后来问了一下同学,思路是这样,先三分x,在三分x的基础上再三分y在y里面找一个满足条件的最小的一个,大题思路是这样,具体实现见代码。

代码:

#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<ctime>
using namespace std;
int n; //n栋楼
double minx,miny,maxx,maxy;  //找到四个边界
double ansx,ansy,sum;  //最后的结果
double midy;  //便于最后输出
double eps=0.001;
struct mq
{double x;double y;int peo;
};
mq node[1005];double dis(double px,double py)  //算sum值
{int i;double sum=0;for(i=0;i<n;i++)sum+=sqrt((px-node[i].x)*(px-node[i].x)+(py-node[i].y)*(py-node[i].y))*node[i].peo;return sum;
}double cal(double x)  //每次返回x确定三分y使得dis(x,y)最小的x,y.{double lefty,righty,mimidy;lefty=miny,righty=maxy;while(righty-lefty>eps){midy=(lefty+righty)/2.0,mimidy=(righty+midy)/2.0;if(dis(x,midy)<dis(x,mimidy))righty=mimidy;elselefty=midy;}return dis(x,midy);}int main()
{int i;//freopen("input.txt","r",stdin);//freopen("output.txt","w",stdout);while(~scanf("%d",&n))  //n栋楼{scanf("%lf%lf%d",&node[0].x,&node[0].y,&node[0].peo);minx=maxx=node[0].x; miny=maxy=node[0].y;for(i=1;i<n;i++)   //找到四个边界{scanf("%lf%lf%d",&node[i].x,&node[i].y,&node[i].peo);if(node[i].x<minx) minx=node[i].x;if(node[i].x>maxx) maxx=node[i].x;if(node[i].y<miny) miny=node[i].y;if(node[i].y>maxy) maxy=node[i].y;}double leftx,rightx,midx,mimidx;leftx=minx,rightx=maxx;while(rightx-leftx>eps)  //三分x的基础上三分y,找到最小的.感谢小雨,gcz{midx=(leftx+rightx)/2.0,mimidx=(rightx+midx)/2.0;if(cal(midx)<cal(mimidx))rightx=mimidx;elseleftx=midx;}ansx=midx,ansy=midy;sum=dis(ansx,ansy);cout<<"便利店选址坐标为:"<<endl;cout<<"x: "<<ansx<<"   "<<"y: "<<ansy<<endl;cout<<"最优解为: "<<sum<<endl;}return 0;
}/*
8
10 20 30
30 34 45
19 25 28
38 49.1 8
9 38.1 36
2 34 16
5 8 78
29 48 56
便利店选址坐标为:
x: 16.5389   y: 27.4345
最优解为: 5146.85
*/

2013数据结构课程设计之便利店选址(暴力枚举或随机函数或三分)相关推荐

  1. c语言超市选址问题实验报告,数据结构课程设计-超市选址问题.doc

    数据结构 课程设计报告 设计题目:学校超市选址问题 专 业 计算机科学与技术 班 级 10计本2班 学 生 朱冬 学 号 联系方式 年 学期 问题描述 对于某一学校超市,其他各单位到其的距离不同,同时 ...

  2. 数据结构课程设计 神秘国度的爱情故事

    数据结构 课程设计报告 广州大学 计算机科学与网络工程学院 计算机系 17级计科专业2班 2019年6月30日 广州大学学生实验报告 开课学院及实验室:计算机科学与工程实验室              ...

  3. 家族关系查询系统程序设计算法思路_数据结构课程设计--

    数据结构课程设计-- 家族关系查询系统 课 程 设 计 任 务 书 题目题目 家族关系查询系统家族关系查询系统 主要内容.基本要求.主要参考资料等主要内容.基本要求.主要参考资料等 主要内容主要内容 ...

  4. 校园导游系统数据结构课程设计(附完整代码)

    1 问题内容与目的要求 1.1 算法产生的背景: Floyd 算法又称为加点法.插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法.该算法名称以创始人之一.1978 年图灵奖获 ...

  5. 山东大学数据结构课程设计实验五(低风险出行系统)

    数据结构课程设计(五)--低风险出行系统 前言 题目要点 ①生成数据 ②要给定两种最短路解法 ③创立文件 ④模拟时间流动并与用户交互 代码讲解 源代码 写在最后 前言 数据结构课程设计第五题是每一个同 ...

  6. 计算机课程设计收费管理系统,数据结构课程设计报告---收费停车场管理系统

    数据结构课程设计报告---收费停车场管理系统 (20页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 14.9 积分 XX大学计算机与电子 信息学院< ...

  7. 数据结构课程设计——机票售卖系统(C++)

    引言 这学期最后的数据结构课程设计需要我们完成一个简单的小程序,我选择了一个机票售卖系统,实现了一些基本的功能:因为时间给的比较短,又赶在复习周补课,所以并没有什么突出的地方,我就在这里聊聊我的代码实 ...

  8. 数据结构课程设计---最长公共子串

    数据结构课程设计,由用户输入两个字符串串X和Y,再由用户输入一个任意的字符串Z,实现以下功能: ①如果字符串Z是字符串X的子串,则显示Z在X中的位置并记录,如果字符串Z是字符串Y的子串,则显示Z在Y中 ...

  9. 设树采用孩子兄弟表示法存放.用类c语言设计算法计算树的高度.,(数据结构课程设计分类题目.doc...

    (数据结构课程设计分类题目 线性表 顺序表: 1.设有一元素为整数的线性表L=(a1,a2,a3,-,an),存放在一维数组A[N]中,设计一个算法,以表中an作为参考元素,将该表分为左.右两部分,其 ...

最新文章

  1. 报名 | 工业大数据分析:机会与挑战讲座
  2. Hive学习笔记 —— Hive概述
  3. python-scrapy爬虫框架
  4. [置顶]       IE与FireFox的JavaScript兼容问题
  5. Js Tween 实现
  6. 弗拉门戈-吉普赛婚礼-保利剧院
  7. Tessellation细分曲面技术(DX11)
  8. matlab香农编码
  9. 龙果支付 mysql_龙果学院 基于电商业务的企业级大中台从设计到实现(第一阶段) 百度云 百度网盘...
  10. scikit-learn中的KMeans聚类实现
  11. 使用 yarn 安装时,报错node_modules\node sass:Command failed.
  12. c++空指针的定义-0L
  13. 【UCOSii源码解析】任务管理
  14. WPF学习之X名称空间详解
  15. 北京航空航天大学王田苗教授:当前智能机器人发展若干挑战性问题
  16. SQL -- 游标(详细)
  17. insightface 人脸识别
  18. 信号时频域分析 ——EMD/BEMD/LMD 算法原理
  19. Android多线程机制
  20. 重力的动态理论(转)

热门文章

  1. a豆14Pro、惠普战66、联想小新air14plus和宏碁非凡S3哪个好
  2. 解决UITableView下划线左右两边多出来的空白
  3. 考研失败的经验,这些弯路千万别再走了!
  4. nestjs、mongodb
  5. sketch html尺寸,Mac sketch尺寸属性标注插件(Sketch Measure)
  6. 【LeetCode题解】BFS层序遍历二叉树
  7. python绘制对数坐标图描点,python坐标轴对数显示
  8. ABAP使用SE11 search help的方法
  9. 基于SQLiteDatabase的记事本例子
  10. java 中 实现两个整数相除并且保留一位小数