百度面试题

来源:互联网 发布:工资高不加班知乎 编辑:程序博客网 时间:2024/05/16 09:36

有一根27厘米的细木杆,在第3厘米、7厘米、11厘米、17厘米、23厘米这五个位置上各有一只蚂蚁。木杆很细,不能同时通过一只蚂蚁。开始时,蚂蚁的头朝左还是朝右是任意的,它们只会朝前走或调头,但不会后退。当任意两只蚂蚁碰头时,两只蚂蚁会同时调头朝反方向走。假设蚂蚁们每秒钟可以走一厘米的距离。编写程序,求所有蚂蚁都离开木杆的最小时间和最大时间。
 

 

解法一:

最小11,最大就....32种走法,用程序模拟算比较简单,如果找算法规律.....就.....

正解!

每个蚂蚁对象维护自己的几个属性:
time 在木头上走的时间
pos  在木头上的坐标
orientation 方向(-1 or 1)

recursion:
1 所有蚂蚁走一步,矢量pos加1,time加1
2 检查是否有蚂蚁在同一坐标上,如果有,将它们掉头
3 检查是否有蚂蚁的坐标在[0,27]以外的外围,如果有,记下它的time值,然后这个蚂蚁出局
4 repeat 1-3,直到所有蚂蚁出局。它们time的最大值就是一个解(一共有32个情况,32种解)。

解法二:

class FunnyAnt {
class Ant {
public final static int LEFT = 0;
public final static int RIGHT = 1;
int x;
int direction;
public Ant(int x, int direction) {
this.x = x;
this.direction = direction;
}
public void setDirection(int direction) {
this.direction = direction;
}
public void move() {
if (direction == LEFT) {
x -= 1;
} else {
x += 1;
}
}
public void switchDirection() {
direction = (direction + 1) % 2;
}
public int getX() {
return x;
}
public String getDirection() {
return (direction == LEFT) ? "Left" : "Right";
}
}
public static void main(String[] args) {
Vector v = new Vector();
Vector timerV = new Vector();
FunnyAnt fa = new FunnyAnt();
int[] positions = {3, 7, 11, 17, 23};
Ant ant = null;
// list all conditions
for (byte i = 0; i < 32; i++) {
// System.out.println("I :" + i);
int tempI = i;
for (int j = 0; j < 5; j++) {
byte temp = (byte) (tempI & 0x01);
// System.out.println("Position Got :" + temp);
ant = fa.new Ant(positions[j], temp);
v.addElement(ant);
tempI = (byte) (tempI >> 1);
}
int timer = 0;
while (v.size() > 0) {
ant = null;
// move ants if out delete
for (int k = 0; k < v.size(); k++) {
ant = (FunnyAnt.Ant) v.elementAt(k);
ant.move();
int x = ant.getX();
if (x <= 1 || x >= 27) {
v.removeElementAt(k);
}
}
timer++;
// check whether there is collide
ant = null;
for (int l = 0, lastX = -1; l < v.size(); l++) {
ant = (FunnyAnt.Ant) v.elementAt(l);
if (lastX == ant.getX()) {
((FunnyAnt.Ant) (v.elementAt(l))).switchDirection();
((FunnyAnt.Ant) (v.elementAt(l - 1))).switchDirection();
}
lastX = ant.getX();
}
}
timerV.addElement(new Integer(timer));
v.removeAllElements();
}
int min = ((Integer) (timerV.elementAt(0))).intValue(), max = ((Integer) (timerV.elementAt(0))).intValue();
Integer value = null;
for (int i = 0; i < timerV.size(); i++) {
value = (Integer) timerV.elementAt(i);
int x = value.intValue();
if (x < min) {
min = x;
}
if (x > max) {
max = x;
}
}
System.out.println("Max :" + max + " Min :" + min);
}
}

 

解法三:

 


//是否所有蚂蚁下杆,i为蚂蚁只数
bool isOut(int *p,int i)
{
 int j=-1;
 while(++j<i)
  if(p[j]!=-1)
   return false;
 return true;
}

//第i+1和第j+1位置蚂蚁是否碰头
bool isEnt(int *p,int i,int j)
{
  return (p[i]==p[j]&&p[i]!=-1&&p[j]!=-1)?true:false;
}

int main(void)
{
   //初始运动方向计数
   unsigned short int count=0;
   //a[0..4]代表3cm,7cm,11cm,17cm,23cm的运动方向,false为向右
   bool a[5]={false,false,false,false,false};

   unsigned short int i=1;
   //蚂蚁开始运动方向最多32(2的5次方)种
   for(count;count<32;count++){
    //设置5只蚂蚁初始运动方向
    //打印出蚂蚁初始运动方向
      for(int j=0;j<5;j++){
    //因为count总小于32,所以高21位总是0
         a[j]=count&(i<<j);
   printf("%d ",a[j]);
      }
   printf("/n");
   //pos[0..4]代表蚂蚁初始位置,若第i只蚂蚁离开杆则pos[i-1]=-1
   int pos[5]={3,7,11,17,23};
      i=1;
   //t为时间
      for(int t=1;t;t++){
    //蚂蚁下一秒位置
         for(int j=0;j<5;j++){
    if(pos[j]!=-1){
     if(a[j])pos[j]++;
     else pos[j]--;
     //蚂蚁下杆
     if(pos[j]<=0||pos[j]>=27)pos[j]=-1;
    }
   }
   //看相邻两只蚂蚁是否碰头,碰头调转方向
   for(int s=0;s<4;s++){
    if(isEnt(pos,s,s+1)){
     a[s]=!a[s];
     a[s+1]=!a[s+1];
    }
   }
   //是否所有蚂蚁下杆
   if(isOut(pos,5)){
         printf("count:%d/n",t);
         break;
   }
   }
   }
   return 0;
}

来自 http://community.csdn.net/Expert/topic/5141/5141367.xml?temp=.8952143

本人整理

 

原创粉丝点击