今天早上过来就看到有人提了这么一个有趣的问题:
有一根长27厘米的小木棍儿,在木棍儿的3厘米,7厘米,11厘米,17厘米,23厘米的地方各有一只蚂蚁。这5只蚂蚁的走向是不知道的,假设小木棍儿很细只能通过一只蚂蚁。蚂蚁只能往前走或者掉头,不能后退(也就是不能倒着走)!当任意两只蚂蚁碰头的时候会同时掉头朝反方向走。假设蚂蚁一秒钟能走一厘米,求蚂蚁全部离开木棍儿的最小和最大时间。用程序设计出来,可以只写思路!
想了一下,对于每个蚂蚁来说主要有以下几个属性:
time 在木头上走的时间
pos 在木头上的坐标
orientation 方向(即:蚂蚁是否要掉头,-1---左 ,1---右)
步骤:
1.所有蚂蚁走一步,矢量pos加1,time加1
2.检查是否有蚂蚁在同一坐标上,如果有,将它们掉头
3.检查是否有蚂蚁的坐标在[0,27]以外的外围,如果有,记下它的time值,然后这个蚂蚁出局
4.反复1-3步,直到所有蚂蚁出局。它们time的最大值就是一个解(一共有32个情况,32种解).
其实你只要考虑最中间和最外面的那2个蚂蚁就可以了,因为最中间那个也就是11cm的那个蚂蚁用时是最少的,为11s,而用时最大的就是那个3cm的蚂蚁,用时24s,只要把这2个判断好就可以了,其他的可以忽视。
在第2步中,蚂蚁碰头同时掉头朝反方向走,可以理解成只要把2只蚂蚁位子置换一下就可以了,这样就可以理解为什么最大是24s了,因为3cm的蚂蚁离另一头是最远的;而用时最少的,就是最接近中间的那只蚂蚁了,也就是11cm处的那个蚂蚁。
public class Test {
static int[] state = new int[5]; // -1:left; 1:right
static int ss = 0; // 结果
static int[] pos = { 3, 7, 11, 17, 23 };
static int start = 0;
static int end = 27;
static void go() {
while (true) {
ss++;
for (int i = 0; i < pos.length; i++) {
if (pos[i] > 0 && pos[i] < 27) {
pos[i] += state[i];
if (i < pos.length - 1 && state[i] == 1
&& state[i + 1] == -1) {
// 碰头情况
if (pos[i] + 1 > pos[i + 1]) {
state[i] = -1;
state[i + 1] = 1;
}
}
if (i > 0 && state[i] == -1 && state[i - 1] == 1) {
// 碰头情况
if (pos[i] - 1 < pos[i - 1]) {
state[i] = 1;
state[i - 1] = -1;
}
}
}
}
if (proof()) {
print();
break;
}
}
}
private static void print() {
System.out.println(ss);
}
private static boolean proof() {
boolean isOk = true;
for (int i = 0; i < state.length; i++) {
if (pos[i] > 0 && pos[i] < 27) {
isOk = false;
}
}
return isOk;
}
static void init() {
ss = 0;
pos[0] = 3;
pos[1] = 7;
pos[2] = 11;
pos[3] = 17;
pos[4] = 23;
}
public static void main(String[] args) {
state[0] = -1;
state[1] = -1;
state[2] = -1;
state[3] = 1;
state[4] = 1;
// 共32种情况
for (int i = 0; i < 32; i++) {
String s = Long.toBinaryString(i);
int n = 5 - s.length();
for (int j = 0; j < n; j++) {
s = "0" + s;
}
for (int j = 0; j < s.length(); j++) {
char a = s.charAt(j);
if (a == '1')
state[j] = 1;
else
state[j] = -1;
}
init();
go();
}
}
}
分享到:
相关推荐
首先,我们来看看标题中提到的有趣问题:`String str=new String("abc");` 这行代码会创建几个String对象。答案是两个。`"abc"`在Java中是一个字面量,它在运行时会被自动放入字符串池。`new String("abc")`则会创建...
这个问题不仅是计算机科学中的一个有趣问题,而且也是图论和组合数学的重要应用之一。 #### 二、启发式算法在骑士游历问题中的应用 骑士游历问题可以通过多种算法来解决,其中回溯算法是一种非常有效的方法。然而...
一个有趣的问题 培训与认证 安全分析 安全建设 安全研究 网络与基础架构安全
刚刚从别的网站上面看到一个很有趣的用户注册判断功能,是关于钓鱼岛归属问题的一个判断,JS做的,很有趣。看看吧?!
标题 "概率史上一个有趣的问题" 暗示我们要探讨的是概率论中一个具有历史背景的趣味问题,而描述中提到的“Python模拟”则表明我们将使用Python编程语言来重现和理解这个问题。通过Python进行模拟,我们可以更好地...
"经典有趣问题:牛吃草问题" 本资源提供了经典的牛吃草问题的解决方案,涵盖了多种吃草场景,包括牛吃草、羊吃草、马吃草、牛羊一起吃草、马羊一起吃草等多种情况。通过对牛吃草问题的分析,我们可以学习到如何解决...
问题一:如何用一枚硬币等概率地产生一个 1 到 3 之间的随机整数? 这道题考察了程序员对概率论的理解和应用能力。解决这个问题需要使用条件概率和随机事件的知识。对于公正的硬币,投掷两次可以产生 1 到 3 之间的...
删数问题是一个有趣的数学问题,也与算法设计相关。这个问题的基本形式是:给定一个数列,要求删除最少的数,使得剩下的数列是递增的。解决此类问题,可以使用贪心策略,每次删除当前序列中的最大值,直到序列变得...
这些脚本可以提供一个学习如何利用Python解决实际问题的良好平台,包括但不限于数据分析、自动化任务、文本处理、网络编程等。 在压缩包中的"python-gems-master"文件名可能指的是一个包含多个子目录和文件的主目录...
数论中一个有趣的题目:任意一个正整数,若为偶数,则用2除之,若为奇数,则与3相乘再加上1。重复此过程,最终得到的结果为1。如: 21 3105168421 63105168421 编写代码并验证结论
本主题“一个有趣的有限状态机的JAVA实现”将带你探索如何利用Java语言构建一个能解决有趣问题的状态机,比如“如何把大象塞进冰箱”。 首先,让我们理解有限状态机的基本概念。有限状态机是一种数学模型,它由一组...
8.5题是一个字符串反向存储的问题,需要编写一个函数接收一个字符串,然后将其字符顺序反转并返回。这可以通过双指针或者栈等数据结构实现。 8.8题要求输入一个四位数字,并以每两位之间空一格的形式输出,例如将...
本压缩包“有趣的跳跃的测试用例jolly.rar”包含了一个名为“jolly”的测试用例,适用于C++编程语言,主要探讨的是一个可能涉及数组或序列操作的问题。下面我们将深入探讨这个测试用例以及如何使用lemon和cena这两个...
总结来说,残缺棋盘问题是一个有趣的组合优化问题,通过C语言和回溯算法可以有效地求解。解决这个问题不仅可以提升编程技巧,还能加深对图论和回溯策略的理解。如果你对这个话题感兴趣,可以尝试编写代码并调试,以...
13. **概率问题**:在考试中,不定项选择题的猜测难度较高,因为必须选择所有正确答案,而不是只有一个正确答案。概率计算需要考虑所有可能的组合。 以上就是课件中涉及的主要数学知识点,这些内容对于培养学生的...
在本次数据结构课程设计中,我们面临的任务是解决一个有趣的学生搭配问题。问题设定如下:一个班级有m个女生和n个男生(m≠n),他们需要在一个舞会上配对跳舞。男生和女生分别坐在舞池两侧,每次舞蹈开始时,男女各...
题目讲述了一个有趣的数学逻辑问题,涉及到了数学中的循环和条件判断等内容。在这个问题中,假设有一群海盗,他们共得到了一些椰子,打算平均分配。但为了公平起见,决定每个人轮流进行分配,并且每次分配后剩余的...
分治问题是指将一个复杂的问题分解成多个小的问题,然后分别解决这些小问题,并将结果组合起来得到最终的解答。例如,在1006乘积最大问题中,使用了分治的思想,将问题分解成多个小的问题,然后使用动态规划来解决...
在Android平台上,创建一个有趣的锁屏程序,要求用户正确回答问题才能进行锁屏操作,是一项既挑战性又具有趣味性的任务。这样的应用可以提高用户的互动性,并为日常的锁屏体验带来新的乐趣。下面我们将详细探讨如何...