题目描述:
有一根27厘米的细木杆,在第3厘米、7厘米、11厘米、17厘米、23厘米这五个位置上各有一只蚂蚁。木杆很细,不能同时通过一只蚂蚁。开始时,蚂蚁的头朝左还是朝右是任意的,它们只会朝前走或调头,但不会后退。当任意两只蚂蚁碰头时,两只蚂蚁会同时调头朝反方向走。假设蚂蚁们每秒钟可以走一厘米的距离。编写程序,求所有蚂蚁都离开木杆的最小时间和最大时间。
在网上无意间看到这个小问题,觉得挺有趣的,自己分析后给出了递归方法来处理它
算法思想、步骤都在code的注释里有所解释
package com.leochan;
import java.util.LinkedList;
public class RecursionAntWalker {
public static int spendTime = 0;
public static int totalLength = 27;
public static void main(String[] args) {
recursionTest();
}
// 递归计算32种不同情况下所需要的时间。
private static void recursionTest() {
int count = 0;
for (int d1 = -1; d1 <= 1; d1 += 2) {
for (int d2 = -1; d2 <= 1; d2 += 2) {
for (int d3 = -1; d3 <= 1; d3 += 2) {
for (int d4 = -1; d4 <= 1; d4 += 2) {
for (int d5 = -1; d5 <= 1; d5 += 2) {
count++;
spendTime = 0;
Ant a = new Ant(3);
Ant b = new Ant(7);
Ant c = new Ant(11);
Ant d = new Ant(17);
Ant e = new Ant(23);
a.direction = d1;
b.direction = d2;
c.direction = d3;
d.direction = d4;
e.direction = d5;
LinkedList<Ant> testCase = new LinkedList<Ant>();
testCase.add(a);
testCase.add(b);
testCase.add(c);
testCase.add(d);
testCase.add(e);
System.out.print("count=" + count + " d1=" + d1
+ " d2=" + d2 + " d3=" + d3 + " d4=" + d4
+ " d5=" + d5);
System.out
.println(" getTime=" + getTime(testCase));
}
}
}
}
}
}
// 递归计算每种组合需要的时间
public static int getTime(LinkedList<Ant> antList) {
int len = antList.size();
// 如果antList里没有蚂蚁,直接返回spendTime
if (len == 0)
return spendTime;
// 如果antList里只有1只蚂蚁,让这种蚂蚁一直走下去,直到它达到边界。
// 在spendTime和这只蚂蚁所走过的distance中取最大值做为最终花费的时间
if (len == 1) {
Ant onlyAnt = antList.getFirst();
onlyAnt.keepWalking();
return (spendTime > onlyAnt.distance) ? spendTime
: onlyAnt.distance;
}
// 如果antList里的第一只蚂蚁的运动方向为负方向,即-1,
// 就重新计算spendTime,并且将这只蚂蚁移出list,递归去getTime
if (!antList.getFirst().positiveDirect()) {
Ant currentAnt = antList.removeFirst();
spendTime = (currentAnt.position > spendTime) ? currentAnt.position
+ currentAnt.distance : spendTime;
}
// 如果antList里最后一只蚂蚁的方向为正方向,即1
// 就重新计算spendTime,并且将这只蚂蚁移出list,递归去getTime
else if (antList.getLast().positiveDirect()) {
Ant currentAnt = antList.removeLast();
int needToGo = totalLength - currentAnt.position;
spendTime = (needToGo > spendTime) ? needToGo + currentAnt.distance
: spendTime;
}
// 其他情况下,让所有的蚂蚁按方向走一步,并判断有没有2只蚂蚁的位置重合,
// 如果有重合,就让对应的2只蚂蚁转向。
else {
for (int i = 0; i < len; i++) {
antList.get(i).walking();
if (!antList.get(i).positiveDirect()) {
if (antList.get(i).checkPosition(antList.get(i - 1))) {
antList.get(i).changedirect();
antList.get(i - 1).changedirect();
}
}
}
}
return getTime(antList);
}
}
// 蚂蚁类
class Ant {
public int distance = 0; // 走过的距离,数值上等于时间
public int position; // 当前的位置,在0-27之间
public int direction = -1; // 运动的方向,-1表示向左,1表示向右
public Ant(int position) {
this.position = position;
}
// 用来判断运动方向是否为正方向
public boolean positiveDirect() {
return direction > 0;
}
// 如果位置在0-27之间,让蚂蚁一直行走
public void keepWalking() {
while (this.position > 0
&& this.position < RecursionAntWalker.totalLength)
this.walking();
}
// 检查2只蚂蚁的位置是否相同
public boolean checkPosition(Ant ant) {
return this.position == ant.position;
}
// 让当前的蚂蚁转向
public void changedirect() {
direction = -direction;
}
// 让蚂蚁按照自己的方向走1步,即经历单位时间1.
public void walking() {
distance += 1;
position += direction;
}
}
分享到:
相关推荐
Java面试题是每一位希望在软件工程领域,尤其是外企求职的开发者都需要准备的重要内容。这份资源集合了多种Java相关的面试问题,旨在帮助应聘者全面掌握并理解Java编程语言的关键概念和技术。以下是一些可能出现在...
在IT面试中,二叉树的遍历是一个常见的知识点,尤其对于编程岗位来说更是必不可少的考察点。...掌握这些知识点对于理解和解答IT面试中的二叉树问题至关重要,同时也能体现面试者对数据结构和算法的理解程度。
第二种算法则采用了递归的方式,通过递归函数调用自己来完成链表的反转。两种方法都需要注意边界条件,即空链表和只有一个元素的链表不需要进行反转。 在链表的操作中,还有其他一些常见问题,如查找链表的倒数第N...
在编程领域,递归是一种强大的工具,...总之,Java中的递归实现阶乘是一个经典的示例,它展示了递归在解决数学问题时的威力和优雅。通过理解和实践这个例子,你可以更好地掌握递归的概念,并将其应用于更复杂的问题中。
转换河内塔问题的递归解法为非递归解法,可以帮助我们深入理解问题的本质,并且提供了一种解决复杂问题的新视角。这种技巧对于处理其他递归问题,如树的遍历、图的搜索等问题,也有一定的启发作用。 在提供的压缩包...
汉诺塔的非递归解法,十分神奇,值得借鉴! 汉诺塔的非递归解法,十分神奇,值得借鉴! 汉诺塔的非递归解法,十分神奇,值得借鉴! 汉诺塔的非递归解法,十分神奇,值得借鉴! 汉诺塔的非递归解法,十分神奇,值得...
### Java使用递归实现字符串反转 在Java编程语言中,递归是一种常用的方法来解决许多问题,特别是那些可以通过分解成更小子问题来解决的问题。本文将详细介绍如何使用递归来实现字符串的反转。 #### 一、递归基础...
### queen问题的递归解法解析 #### 一、皇后问题背景与定义 皇后问题,又称八皇后问题,是国际象棋中一个经典的数学问题,最早由德国国际象棋问题专家马克斯·贝塞尔在1848年提出。这个问题是在8×8的国际象棋棋盘...
第33题“搜索旋转排序数组”是一个经典的问题,它涉及到数组处理、二分查找以及对特殊情况的处理,这些都是Java开发者必备的技能。现在我们来深入探讨这个题目及其解法。 **题目描述:** 给定一个旋转排序的数组,...
Java语言中实现0-1背包的递归解法通常会使用一个二维数组dp,其中dp[i][j]表示在前i个物品中,容量为j时的最大价值。递归函数可以如下表示: ```java int knapsack(int W, int[] w, int[] v, int n) { int[][] dp ...
[6.3.1]--410找零兑换问题的递归解法.srt
[6.3.1]--410找零兑换问题的递归解法.mp4
- `knapsackProblemDP.cpp`:这应该是使用存储优化的递归方法实现的0/1背包问题。 - `knapsackProblemBottomUpDP.cpp`:这个文件实现了自下而上的递归(迭代法),从基本情况开始逐步计算`dp`数组。 - `...
前端大厂最新面试题-Transformer 本文将对前端大厂最新面试题-Transformer进行解读,并从中提炼出相关的知识点。 标题解读 前端大厂最新面试题-Transformer,表明本文是关于前端开发领域的面试题,Transformer是指...
5. **问题分解**:递归通常用于将大问题分解为更小的子问题。例如,计算阶乘可以用递归表示为`n! = n * (n-1)!`,其中1!是基本情况。 6. **尾递归优化**:某些Java编译器支持尾递归优化,这允许在不增加额外堆栈...
### 递归算法Java实现 #### 一、递归算法简介 递归是计算机科学中的一个重要概念,指的是一种函数或过程直接或间接地调用自身的行为。在编程语言中,递归通常用来解决那些可以通过更小规模的问题来解决的大问题。...
在Java面试中,面试官通常会关注候选人的技术深度、广度以及问题解决能力。这份“java面试必问面试宝典--千方百计”很可能是总结了众多面试者的经验,包含了Java核心技术、面试技巧以及应对策略。以下是一些可能涵盖...
递归是一种重要的编程概念,尤其在Java这样的面向对象语言中,它被广泛应用于解决各种复杂问题。递归指的是一个函数或方法在其定义中调用自身的过程。这种技术源自数学和计算机科学,它允许通过简化问题的规模来解决...
"前端大厂最新面试题-tecent" 标题解释 本文档标题为"前端大厂最新面试题-tecent",该标题表示这是一个关于前端面试题的文档,特别是针对腾讯(tecent)公司的面试题。 描述解释 该文档的描述为"前端大厂最新面试...
掌握上述39道JAVA经典算法面试题及其解析,对于任何希望在软件开发行业中取得成功的人来说都是极其宝贵的。通过这些题目的练习,读者不仅能加深对JAVA编程语言的理解,还能提升在实际工作中解决复杂算法问题的能力。...