微软面试题-过桥问题
来源:互联网 发布:彩票缩水软件大全 编辑:程序博客网 时间:2024/04/29 14:07
找工作中,可能要笔试,,有相关智力题,所以做了几道,今天发现了一个过桥问题,好像是一个比较经典的问题,微软用它做过笔试题。
过桥问题 问题:S个人晚上过桥,他们都站在桥的一端,桥上最多只能让N个人过桥。他们有一个手电筒,无论是一个人走还是k(k<=N)个人走,都需要手电筒。但人过桥后,手电筒不能扔过去,只能派人传过去。假设第i个人过桥的时间是Ti,则过桥的最短时间T(S)为?
解:不妨假设过桥时间Ti<=Tj(i<j)。
N递归方案:如果S<=N,则T(S)=max(T1,…,TS)=TS,否则T(S)=T(S-N)+min(S中最后N人过桥时间)。S中最后N人过桥时间最短方式:前N个人过桥,第一个人把手电筒带回,然后最后N个人拿着手电过桥,然后由第2个人把手电带过来。这个时间为F1=max(T1,…,TN)+ T1+max(TS-N+1,…,TS)+ T2= TN+T1+TS+T2。
另外还有一种N-1递归方案:如果S<=N,则T(S)=max(T1,…,TS)=TS,否则T(S)=T(S-N+1)+min(S中最后N-1人过桥时间),具体过法是:第一个人和最后N-1个人过桥,然后第一个人拿着手电筒过来,所需时间F2= max(TS-N+2,…,TS)+T1= TS+T1。
因为N递归方案不一定比N-1递归方案好,但N-1递归方案一定比N-2,…,1递归方案好(显而易见,能够照越多人过越好)
因此:
下去。
例1:S=4,N=2,四个人过桥时间依次为:1,2,5,10分钟。(微软面试题)
第一轮:F1=2+1+10+2=15,F2=10+1=11,T(4)=min{T(2)+15,T(3)+11}
第二轮:对于T(2)=2;对于T(3),F1=2+1+5+2=10,F2=1+5=6,所以T(3)=min{T(1)+10,T(2)+6}=min{11,8}=8。
代入第一轮,得出T(4)=min{2+15,8+11}=17
由于递归计算手算麻烦,编个简单c++程序如下(程序不排序,所以得严格输入):
#include<iostream.h>
int GetT(int *T,int n,int N,bool show)
{
if(n<=N)
{
if(show)
{
for(int i=0;i<n;i++)
cout<<i+1<<",";
cout<<"-->>过去"<<" "<<T[n-1]<<endl;
}
return T[n-1];
}
else
{
int F1=T[0]+T[1]+T[n-1]+T[N-1];
int F2=T[n-1]+T[0];
int T1=GetT(T,n-N,N,false)+F1;
int T2=GetT(T,n-N+1,N,false)+F2;
if(T1<T2)
{
if(show)
{
for(int i=0;i<N;i++)
cout<<i+1<<",";
cout<<"-->>过去"<<" "<<T[N-1]<<endl;
cout<<1<<"把手电带回来"<<" "<<T[0]<<endl;
for(i=0;i<N;i++)
cout<<n-N+1+i<<",";
cout<<"-->>过去"<<" "<<T[n-1]<<endl;
cout<<2<<"把手电带回来"<<" "<<T[1]<<endl;
GetT(T,n-N,N,true);
}
return T1;
}
else
{
if(show)
{
for(int i=1;i<N;i++)
cout<<n-N+i+1<<",";
cout<<1;
cout<<"-->>过去"<<" "<<T[n-1]<<endl;
cout<<1<<"把手电带回来"<<" "<<T[0]<<endl;
GetT(T,n-N+1,N,true);
}
return T2;
}
}
}
void main()
{
int S;
int N;
int ret;
cout<<"请输入总的过桥人数"<<endl;
cin>>S;
cout<<"请输入一次能过的人数"<<endl;
cin>>N;
int *T=new int[S];
cout<<"请依次输入过桥的时间,按照从小到大顺序输入!"<<endl;
for(int i=0;i<S;i++)
cin>>T[i];
cout<<"-----------------具体过桥方案为:------------------"<<endl;
ret=GetT(T,S,N,true);
cout<<"----------------"<<endl;
cout<<"最少时间为:"<<ret<<endl;
delete []T;
}
程序运行结果:
解:不妨假设过桥时间Ti
N递归方案:如果S<=N,则T(S)=max(T1
另外还有一种N-1递归方案:如果S<=N,则T(S)=max(T1
因为N递归方案不一定比N-1递归方案好,但N-1递归方案一定比N-2,…,1递归方案好(显而易见,能够照越多人过越好)
因此:
例1:S=4,N=2,四个人过桥时间依次为:1,2,5,10分钟。(微软面试题)
第一轮:F1=2+1+10+2=15,F2=10+1=11,T(4)=min{T(2)+15,T(3)+11}
第二轮:对于T(2)=2;对于T(3),F1=2+1+5+2=10,F2=1+5=6,所以T(3)=min{T(1)+10,T(2)+6}=min{11,8}=8。
代入第一轮,得出T(4)=min{2+15,8+11}=17
由于递归计算手算麻烦,编个简单c++程序如下(程序不排序,所以得严格输入):
#include<iostream.h>
int GetT(int *T,int n,int N,bool show)
{
if(n<=N)
{
if(show)
{
for(int i=0;i<n;i++)
cout<<i+1<<",";
cout<<"-->>过去"<<" "<<T[n-1]<<endl;
}
return T[n-1];
}
else
{
int F1=T[0]+T[1]+T[n-1]+T[N-1];
int F2=T[n-1]+T[0];
int T1=GetT(T,n-N,N,false)+F1;
int T2=GetT(T,n-N+1,N,false)+F2;
if(T1<T2)
{
if(show)
{
for(int i=0;i<N;i++)
cout<<i+1<<",";
cout<<"-->>过去"<<" "<<T[N-1]<<endl;
cout<<1<<"把手电带回来"<<" "<<T[0]<<endl;
for(i=0;i<N;i++)
cout<<n-N+1+i<<",";
cout<<"-->>过去"<<" "<<T[n-1]<<endl;
cout<<2<<"把手电带回来"<<" "<<T[1]<<endl;
GetT(T,n-N,N,true);
}
return T1;
}
else
{
if(show)
{
for(int i=1;i<N;i++)
cout<<n-N+i+1<<",";
cout<<1;
cout<<"-->>过去"<<" "<<T[n-1]<<endl;
cout<<1<<"把手电带回来"<<" "<<T[0]<<endl;
GetT(T,n-N+1,N,true);
}
return T2;
}
}
}
void main()
{
int S;
int N;
int ret;
cout<<"请输入总的过桥人数"<<endl;
cin>>S;
cout<<"请输入一次能过的人数"<<endl;
cin>>N;
int *T=new int[S];
cout<<"请依次输入过桥的时间,按照从小到大顺序输入!"<<endl;
for(int i=0;i<S;i++)
cin>>T[i];
cout<<"-----------------具体过桥方案为:------------------"<<endl;
ret=GetT(T,S,N,true);
cout<<"----------------"<<endl;
cout<<"最少时间为:"<<ret<<endl;
delete []T;
}
程序运行结果:
- 微软面试题-过桥问题
- 面试题之一过桥问题
- 关于微软面试题:"四人过桥"问题的思考——“n人过桥”问题的演进(Java实现)
- 关于微软面试题:"四人过桥"问题的思考——“n人过桥”问题的演进(Java实现)
- 【算法面试题】:小明过桥问题
- 微软过桥问题
- 《吃豆子过桥问题》——经典智力题、面试题
- 《吃豆子过桥问题》——经典智力题、面试题
- 微软面试题---阶乘问题
- 微软过桥问题Dijkstra/倒水问题
- 微软面试题----钢管取球问题
- 北美微软面试题---数组问题
- 23. 微软面试题:跳台阶问题
- 微软面试题【飞机加油问题】题解
- 微软面试题病狗问题
- 微软面试题【飞机加油问题】题解
- 微软过桥问题的图论解法
- 微软过桥问题与测试人员素养
- 当前世界金融危机的通俗解释
- 李一男:百度的发动机
- 浅析云计算的七种应用类型
- VS2005 C# WEB swf 文件背景透明
- Linux 的经典命令:
- 微软面试题-过桥问题
- free software
- MD5 计算方法( 一 ) -- MD5 规范计算函数
- ]《士兵突击》之班长史今:残酷青春我们最想遇见的那个人
- ibatis学习记录(4)
- 搜索内存数据(-)
- SQL Server select语句执行顺序
- ]《士兵突击》之班长史今:残酷青春我们最想遇见的那个人
- 搜索内存数据(二)