面试笔试题——12个工厂分布在一条东西向高速公路的两侧......

半夜郎中 2011-07-28 02:40:35
12个工厂分布在一条东西向高速公路的两侧,工厂距离公路最西端的距离分别是0、4、5、10、12、18、27、30、31、38、39、47.在这12个工厂中选取3个原料供应厂,使得剩余工厂到最近的原料供应厂距离之和最短,问应该选哪三个厂 ?
上面是在群里面贴出来的,自己就收藏了一下,想等有空的时候想想。下面我就解这道题的思路说一下,有不对的地方还请指出。
首先要注意在12个工厂中有一个到最西端的为0,我设这一点为第0个工厂,我们可以看到每个工厂都是离最西端一点的距离,那么我们是不是可以将这个问题这样理解?就是所有节点以最西端为圆心的一个圆,那么第0个工厂就是在圆心位置(因为它离最西端为零),那么就可以将上面的问题描述成下面的一个图:

个人认为这个工厂位置可以通过上图描述出来。那么得到这样一个图如何求选择哪三个工厂作为原料厂呢?下面将进行讲解:
我们假设原则的三个原料厂为p、q、r。那么所有节点到离其最进的原料厂的距离之和为最小时,则这三个厂为原料厂。要求得图中每个节点到其的最短距离这是一个Dijkstra算法,所以此处需要对图中所有节点求一次Dijkstra算法,我们通过一个Map来存储,Map的key为当前Dijkstra的源点,值为通过Dijkstra算得的dist[]数组。此时我们就得到了所有节点的Dijkstra的dist[]数组,并将其进行存储在Map中。那么如何取得三个原料厂呢?那就是从这12个厂中任选三个,并求的所有节点到离其最近的原料厂的距离之和,我们将这个和赋给一个tempmin变量。如何任选三个工厂,那么就需要使用三重循环,其实这里是个排列组合,那么共有12*12*12种,但注意还要减去不能选择相同工厂的情况,就是通过一个if判断来避免选择相同工厂的情况,当我们任选了三个工厂作为原料厂,那么就需要求的所有节点(但必须出去已被选定作为原料厂的工厂)到和其最近的原料厂距离之和,同时赋给tempmin,注意该变量是记录每任取三个原料的距离之和。取得每次的距离之和在进行比较,将会产生一个最短的情况,那么这种情况的所选的三个原料厂是最好的情况。详细代码如下:
public class Factory{

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
float[][] a = new float[12][12];
for (int i = 0; i < 12; i++) {
for (int j = 0; j < 12; j++) {
if (i == j) {
a[i][j] = 0;
} else {

a[i][j] = Float.MAX_VALUE;
}
}

}
a[0][1] = 4;
a[1][0] = 4;
a[0][2] = 5;
a[2][0] = 5;
a[0][3] = 10;
a[3][0] = 10;
a[0][4] = 12;
a[4][0] = 12;
a[0][5] = 18;
a[5][0] = 18;
a[0][6] = 27;
a[6][0] = 27;
a[0][7] = 30;
a[7][0] = 30;
a[0][8] = 31;
a[8][0] = 31;
a[0][9] = 38;
a[9][0] = 38;
a[0][10] = 39;
a[10][0] = 39;
a[0][11] = 47;
a[11][0] = 47;
Float[] dist = new Float[12];
int[] prev = new int[12];
Map<String, Float[]> distMap = new HashMap<String, Float[]>();
List<Float[]> list = new ArrayList<Float[]>(12);
for (int i = 0; i < 12; i++) {
//System.out.print(i+"--->");
dijkstra(i, a, dist, prev);
distMap.put(i+"f", dist);
/*for(int j=0; j<12; j++)
{
System.out.print(dist[j]+" ");
}
System.out.println();*/
dist = new Float[12];
//System.out.println();
}
float min = Float.MAX_VALUE;
int p = -1, q=-1, r=-1;
Map<String, Float[]> tempMap = new HashMap<String, Float[]>();
for (int i = 0; i < 12; i++) {
for (int j = 0; j < 12; j++) {
for (int k = 0; k < 12; k++) {
if(i!=j&&i!=k&&j!=k)
{
tempMap.put(i+"y", distMap.get(i+"f"));
tempMap.put(j+"y", distMap.get(j+"f"));
tempMap.put(k+"y", distMap.get(k+"f"));
float tempmin = 0.0f;
for (int m = 0; m < 12; m++) {
float temp = Float.MAX_VALUE;
if (m != i && m != j && m != k) {
//取得当前的点到当前所选的

三个原料厂中那个地点最短
for (Map.Entry<String,

Float[]> entry : tempMap
.entrySet

()) {
if (temp >

entry.getValue()[m]) {
temp =

entry.getValue()[m];
}
}

//此处是求的当前所选的三个

节点,所有节点到和其最进的节点距离之和
tempmin+=temp;
}
}
tempMap.clear();
//比较整个最小
System.out.println("最小和为: "+tempmin+"

三个原料厂为:"+i+" "+j+" "+k);
if(min>tempmin)
{
min=tempmin;
p=i;
q=j;
r=k;
}
}
}
}
}
System.out.println("最小和为: "+min+"三个原料厂为:"+p+" "+q+"

"+r);
}

public static void dijkstra(int v, float[][] a, Float[] dist, int[] prev)

{
int n = dist.length - 1;
if (v < 0 || v >n)
return;
boolean[] s = new boolean[n + 1];
//此处的循环是初始化
for (int i = 0; i <= n; i++) {
dist[i] = a[v][i];
s[i] = false;
if (dist[i] == Float.MAX_VALUE)
prev[i] = -1;
else
prev[i] = v;
}
//此处开始遍历
dist[v] = 0.0f;
s[v] = true;
//该循环是求的所有节点到源节点的路径,每循环一次求的一个节点到源节

点的距离
for (int i = 0; i <=n; i++) {
float temp = Float.MAX_VALUE;
int u = v;
//shortestPath(此处取该循环为shortestPath)
for (int j = 0; j < n; j++) {
if ((!s[j]) && (dist[j] < temp)) {
u = j;
temp = dist[j];
}
}
//System.out.print(u+" dist:"+dist[u]+" ");
s[u] = true;
//updateDist(取名为updateDist)
for (int j = 0; j <=n; j++) {
if ((!s[j]) && (a[u][j] < Float.MAX_VALUE)) {
float newdist = dist[u] + a[u][j];
if (newdist < dist[j]) {
dist[j] = newdist;
prev[j] = u;
}
}
}
}
}

}
...全文
398 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
半夜郎中 2011-07-28
  • 打赏
  • 举报
回复
大家看看这个人的解法!
http://hi.baidu.com/unixfy/blog/item/9db8e06ab053f0c080cb4a47.html
飞跃颠峰 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 jdream314 的回复:]

这个想法有待探讨!!!大家讨论一下
[/Quote]

嘿嘿,你再看下题目就明白了。

为什么要强调东西向的高速公路?就是保证高速公路不拐弯的,纯直线
工厂全在路边上,所以全在一条直线上
半夜郎中 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 alexandertech 的回复:]

12个工厂分布在一条东西向高速公路的两侧,工厂距离公路最西端的距离分别是0、4、5、10、12、18、27、30、31、38、39、47.

高速公路表示12个厂全部在一条直线上
所以任意两个厂的距离就是它们距离最西端的距离的差值

如第1厂到2厂的直线距离=5-1=1
第2厂到3厂的直线距离=10-5=5

如果把第0厂作为圆心作图去算距离,反而不对了
[/Quote]
这个想法有待探讨!!!大家讨论一下
飞跃颠峰 2011-07-28
  • 打赏
  • 举报
回复
12个工厂分布在一条东西向高速公路的两侧,工厂距离公路最西端的距离分别是0、4、5、10、12、18、27、30、31、38、39、47.

高速公路表示12个厂全部在一条直线上
所以任意两个厂的距离就是它们距离最西端的距离的差值

如第1厂到2厂的直线距离=5-1=1
第2厂到3厂的直线距离=10-5=5

如果把第0厂作为圆心作图去算距离,反而不对了
半夜郎中 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 bayougeng 的回复:]

我觉得要是不给出这几个工厂的分布位置的话,仅凭简单的两个点之间的距离,无法计算吧。
题说的很清楚,是分布在公路两侧啊,两个工厂间是否有直路?如果没有,那就都要走那条东西向的公路,所以必须知道公路的分布。如果有的话,那题目为什么要给出有条公路的条件呢?这条公路没什么意义嘛。
[/Quote]
主要是题中没有给出工厂的分布位置
半夜郎中 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 alexandertech 的回复:]

我觉得你把这个题搞复杂了,又是图又是Dijkstra算法的
如果我没理解错,任意两个节点之间的距离就是它们之间的直线距离(无所谓最大或最小)
[/Quote]
主要我们不知道两个点之间的直线距离啊!所以就得通过图的知识来处理!
要是知道节点为分布位置,知道两个节点之间的直线距离
那么这个题目就没意思了!
飞跃颠峰 2011-07-28
  • 打赏
  • 举报
回复
我觉得你把这个题搞复杂了,又是图又是Dijkstra算法的
如果我没理解错,任意两个节点之间的距离就是它们之间的直线距离(无所谓最大或最小)
bayougeng 2011-07-28
  • 打赏
  • 举报
回复
我觉得要是不给出这几个工厂的分布位置的话,仅凭简单的两个点之间的距离,无法计算吧。
题说的很清楚,是分布在公路两侧啊,两个工厂间是否有直路?如果没有,那就都要走那条东西向的公路,所以必须知道公路的分布。如果有的话,那题目为什么要给出有条公路的条件呢?这条公路没什么意义嘛。
半夜郎中 2011-07-28
  • 打赏
  • 举报
回复
自己抢个沙发

50,530

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧