组合数学

数字推理

3,8,24,63,143 ,()

3=2*2-1

8=3*3-1

24=5*5-1

63=8*8-1

143=12*12-1

序列为2 3 5 8 12

相邻两数间隔1 2 3 4 5

因此下一个数17

17*17-1=288

组合数学

###How many rectangles you can find from 3*4 grid?

因为每两条横线与两条竖线可以组成一个矩形, 共有4条横线,5条竖线 , 因此共有 C(4,2)C(5,2)=610=60 个矩形 。

##智力题

###小松鼠运坚果

小松鼠采到了100 颗坚果要运回家。家离放坚果的地方有100 米远。小松鼠每次最多运 50 颗。BUT!小松鼠很馋。。。每走2 米就要吃一颗坚果。。。返回时不会再吃坚果,问小松鼠最多能运回家多少颗坚果?

让松鼠走到离家50米的地方停止,把剩下的25个坚果放下,回去拿剩下的50个,然后到刚才放坚果的地方停下,这时候还有50个坚果,距离家的距离为50米,最后到家的时候吃25个,还剩下25个

设采坚果的地点为A,家为B,从A到B方向的运动需要消耗坚果。题目求最多运多少坚果回家,为使结果最大化,所以需要每次开始都运50颗,所以题目也就是求最少的坚果消耗量,由于A->B方向的运动一直要消耗坚果,所以也就是求此方向运动的最少距离。由于每次做多运50颗,所以有一段A->B方向必须走两次,设这段距离为x,剩下的距离为y,则有x+y=100。消耗的总坚果数为(2x+y)/2。并且为了使最后y段能够运走所有2x段剩下的坚果,需要满足2*(50-x/2)<=50,所以x>=50。由于要使(2x+y)/2=(x+100)/2最小,所以x应该去最小值50,所以消耗坚果数为(50+100)/2=75,所以剩下25个。

###在一个游戏的任务中,玩家需要进入1个山洞,取得宝石,之后回到入口.

山洞的地图如下:

​ S--------------------T

S是入口

T处有宝箱,打开宝箱之后可能得到的物品有:

1)宝石,出现概率为5%.

2)魔法券.出现概率为50%.玩家每消耗一个魔法券,可以直接传送到入口S.

3)什么也没有,概率为45%.

S到T的距离为1.

每次玩家回到S之后,宝箱T的状态会重置,再次进入山洞可以重新打开宝箱获得物品.

玩家的任务是到达T获取宝石之后回到入口S.如果到达T之后没有获得宝石,可以走出山洞之后

再进入反复刷.

问题:玩家完成任务所走路程的数学期望是()

因为宝石,出现概率为5%, 不管如何,出现要完成任务的期望次数是20次,大约10次不会有传送,那么就是20步

那么剩下10次会传送,那么是10步,总共30步

理论上,5% * 20=1,所以走了20次,开了20次宝箱,因为有往返过程,所以20*2=40,又因为在走40趟中,手里有了20 * 50%=10个魔法圈,可以不用用脚回到起点了,可以瞬间转移到起点 所以40-10=30次

可以设期望为x

拿到宝石:路程2

拿到魔法券:则走的路程为(1+x),可理解为先走1个单位的路程,然后直接传送到起点,之后需要行走的路程期望其实和初始时相同为x,故总的路程为(1+x),

什么也没有:走2个单位,回到起点,再开始走时和初始状态一样行走的路程期望也为x,故总的行走路程为(2+x)

综上所述,2*5% + (1+x)*50% + 45% * (2 + x)= x,解方程即可得答案

###选择工厂——最短距离问题

**12个工厂分布在一条东西向高速公路的两侧,工厂距离公路最西端的距离分别是0、4、5、10、12、18、27、30、31、38、39、47。在这12个工厂中选取3个原料供应厂,使得剩余工厂到最近的原料供应厂距离之和最短,问应该选哪三个厂 ? **

5,4,10
27,4,10
0,4,10
5,27,39
img

思路:这道题在开始就诱导人们想两侧,其实不然,我们把工厂位置看成一条线,在里面找3个点, 剩余的工厂到最近的点的距离要尽量地小,那我们这3个点就要尽量分开,可以当成是上面一个,中间一个,下面一个,那这三个点之间必然要间隔这几个工厂,我们再看回选择部分,A选项4和5太近,是不可能的了,B选项的7有点莫名其妙,因为没有这个工厂。C选项的0和4也是相隔太近了。最后自然剩下D了

(1)工厂距离是从小到大排序的。

(2)从N个工厂中选择1个原料厂,选择位于中位数位置的工厂,距离之和最短。

(3)设A[i][j]表示从前i个工厂选择j个原料厂的最短距离 (1<=i<=j<=N)

B[i][j]表示从第i个工厂到第j个工厂选择1个原料厂的最短距离。(1<=j<=i<=N)

(4)从前i个工厂选择j个原料厂,可分为两部分:

从前k个工厂选择j-1个原料厂和从第k+1个工厂到第i个工厂选择1个原料厂(1<=j-1<=k<i, k+1<=i)

若j-1等于0, 则前k个工厂没有原料厂了。

(5)递归解为:

A[i][j] = B[1][i], 即j=1时

A[i][j] = min{ A[k][j-1] + B[k+1][i] },其中1<=j-1<=k<i, k+1<=i

/*---------------------------------------------
*   日期:2015-03-02
*   作者:SJF0115
*   题目: 选择原料工厂(最短距离问题)
*   来源:经典面试题
*   博客:
-----------------------------------------------*/
#include <iostream>
#include <algorithm>
#include <climits>
#include <vector>
#include <math.h>
using namespace std;
 
int fac[100][100];
 
// n工厂个数 count原料厂个数 result原料厂下标集合
vector<int> BestFactoryPoint(int n,int count){
    vector<int> result;
    //[1,n]
    int k;
    for(int i = 1;i <= n;){
        //[1,n]分成两部分[1,k]有count-1个原料厂[k+1,n]有1个原料厂
        k = fac[n][count--];
        // [k+1,n]有一个原料厂,中位点就是原料厂点
        result.push_back(k+1 + (n-k-1)/2);
        // 所有原料厂寻找完毕
        if(count == 0){
            break;
        }//if
        // 如果工厂个数小于原料厂个数
        // 所有工厂全是原料厂
        if(k <= count){
            for(int i = 1;i <= k;++i){
                result.push_back(i);
            }//for
            break;
        }//if
        // 求[1,k]部分
        n = k;
    }//for
    return result;
}
 
// 从[start,end]选择一点使其到其他点的距离最小
int MinDistanceOneFactory(int point[],int start,int end){
    if(start > end){
        return -1;
    }//if
    int mid = (start + end) / 2;
    // 计算距离
    int distance = 0;
    for(int i = start;i <= end;++i){
        distance += abs(point[i] - point[mid]);
    }//for
    return distance;
}
//
int MinDistance(int point[],int n,int count){
    if(n <= 0){
        return -1;
    }//if
    //
    // B[i][j]表示从第i个工厂到第j个工厂设1个原料厂的最短距离
    // i <= j B上三角有用
    int B[n+1][n+1];
    // 计算第i个工厂到第j个工厂设1个原料厂的最短距离
    for(int i = 1;i <= n;++i){
        for(int j = i;j <= n;++j){
            B[i][j] = MinDistanceOneFactory(point,i,j);
        }//for
    }//for
    // A[i][j]表示从前i个工厂中设j个原料厂的最短距离之和
    int A[n+1][n+1];
    // i前i个工厂
    for(int i = 1;i <= n;++i){
        // 设j个原料厂
        // j = 1时
        A[i][1] = B[1][i];
        for(int j = 2;j <= i;++j){
            A[i][j] = INT_MAX;
            for(int k = j-1;k < i;++k){
                int curMin = A[k][j-1] + B[k+1][i];
                if(curMin < A[i][j]){
                    A[i][j] = curMin;
                    fac[i][j] = k;
                }//if
            }//for
        }//for
    }//for
    return A[n][count];
}
 
int main() {
    int array[] = {0, 0, 4, 5, 10, 12, 18, 27, 30, 31, 38, 39, 47};
    int n = 12;
    int count = 3;
    cout<<"最小距离->"<<MinDistance(array,n,count)<<endl;
    vector<int> result = BestFactoryPoint(n,count);
    for(int i = result.size()-1;i >= 0;--i){
        cout<<array[result[i]]<<" ";
    }//for
    cout<<endl;
    return 0;
}

Last updated

Was this helpful?