我在开始使用代码时遇到了问题。
问题的描述如下:
机器人会合: 想象一个房间,其中有n个指定的“位置”,编号为1到n。两个机器人R2和D2被放置在房间内,可能位于不同的位置。对机器人进行编程,以便每当锣响起时,它们根据给定的“地图”同时移动到指定的“下一个”位置。对于每个位置,地图指示下一个应该访问的位置。因此,可以将地图视为函数f,使得对于满足1≤i≤n的每个整数,如果机器人位于位置i,则在听到音簧时,它将移动到位置f(i)。
开发一个程序,作为输入,给出房间中的位置数量,R2和D2的初始位置,以及它们被编程遵循的(公共)地图,确定两个机器人是否会相遇(即,同时在同一位置),如果是的话,他们第一次会面的位置和时间(即,在多少次锣探测之后)。如果机器人永远不会满足,那么该程序应报告该事实。
提示:开发一个模拟两个机器人运动的程序是一个很好的方法。然而,执行这种模拟的程序,仅在机器人相遇时才停止,这不是一个正确的解决方案,因为在机器人永远不会遇到的情况下它被困在一个无限循环中。
输入 输入如下:第一行包含一个正整数n,表示房间中的位置数。 (您可以假设n≤100。)第二行包含两个正整数(在1到n的范围内),分别表示R2和D2的初始位置。第三行包含一系列n个正整数,每个正整数在1到n的范围内,代表地图。对于满足1≤i≤n的每个i,序列中的第i个数字表示在位置i之后立即访问的位置。 (将地图视为函数f,序列中的第i个数字给出值f(i)。)
输出 输出应包括一行“机器人永不满足”或“机器人在移动后在位置p处相遇”,其中p和t正确填充。特别是,p和t应描述机器人第一次会面的位置和时间(即前面的移动次数)。
示例输入:
10
3 4
5 6 8 7 8 1 9 5 4 6
10
3 2
5 6 8 7 8 1 9 5 4 6
10
3 6
5 6 8 7 8 1 9 5 4 6
15
2 10
2 4 7 5 3 4 5 9 11 13 8 6 3 11 14
14
1 12
2 3 4 5 6 7 8 8 10 11 12 13 2 3
对应输出:
机器人永远不会见面。
机器人永远不会见面。
机器人在2次移动后在5号位置相遇。
机器人永远不会见面。
机器人在8次移动后在8号位置相遇
我现在的方法是:
public static String robotsMeet(int R2, int D2, int mapSize, int[] map){
for (int i = map[0]; i < map.length; i++){
R2 *= map[i];
D2 *= map[i];
if (R2 == D2){
return "Robots meet at location " + map[i] + " after "+ i + " moves.";
}
}
return "Robots never meet.";
}
如果我能够在正确的方向或其他方面领先,那将是非常有帮助的。
答案 0 :(得分:0)
作为朝着正确方向迈出的一步,我认为&#34;技巧&#34;要理解位置是数组的偏移量,并且在每一步都需要查看数组并进行更新。至于终极终止条件,这是需要考虑的事情。出于演示目的,我认为如果他们没有在200,000步中相遇,他们就不会,但这不是必要的。所以,我看看那个问题。
另外,我的答案基于&#39;数组&#39;的标签。我怀疑这个问题的真正解决方案实际上是使用图表。
除了如何从文件加载数据外,我使用了一个具有基本数据的$(function(){
OpenFirstWindow()
})
var mywindow;
var mywindow2;
function OpenFirstWindow(){
mywindow= window.open('')
mywindow.document.write('<html><head><title>TITLE</title><body onload="">');
mywindow.document.write("window 1");
mywindow.document.write('</body></html>');
mywindow.print();
mywindow.close()
OpenSecondWindow();
}
function OpenSecondWindow(){
mywindow2= window.open('')
mywindow2.document.write('<html><head><title>TITLE</title><body >');
mywindow2.document.write("window 2");
mywindow2.document.write('</body></html>');
mywindow2.document.close();
mywindow2.print();
mywindow2.close()
}
类(省略了getters / setters)。一个&#34;技巧&#34;我使用的是在创建序列数组时,我调整它以使Input
是伪造的。否则,需要处理文件中基于1的输入的加/减。
[0]
从这个起点开始,神奇就在于基于此输入的处理。同样,应该选择更好的终止条件。 class Input
{
int size = 0;
int r2Start = 0;
int d2Start = 0;
Integer[] sequence = new Integer[0];
...
// takes the integers and creates the array
// assumes that the size is set first, and that there are
// are an equal number of entries for the size of the room
// NOTE: offsets the array by 1 to avoid needing to adjust lookups elsewhere
public Input addSequence(int ... inpSeq)
{
if (inpSeq.length != size) {
throw new IllegalArgumentException("elements and size not equal: "
+ inpSeq.length + " vs. size of " + size);
}
if (sequence.length != size + 1) {
sequence = new Integer[size + 1];
}
int loc = 1;
for (int i : inpSeq) {
sequence[loc++] = i;
}
return this;
}
}
方法(未显示)只采用格式和对象...输入,并通过debugLoc
输出。
System.out.printf(...)
public static Result process(Input inp)
{
Result result = new Result();
// we have offset the sequence so that [0] is bogus
// this avoid adding +1 everywhere, as arrays are 0-based,
// but the input is 1 based; this difference is a silly trick
// and not really a good example. Another way to have handled
// this situation would be to subtract one on the initial load,
// but that makes some debugging more difficult
Integer[] seq = inp.getSequence();
// where r2 is located at the beginning depends upon the location
// in the array; in essence, the beginning # is the entry in the
// array
int r2Loc = seq[inp.getR2Start()];
// same thing for d2
int d2Loc = seq[inp.getD2Start()];
// the total number of iterations
// NOTE: a better terminating condition should be developed
int cntr = 0;
while (! result.isMet() && cntr < 200000) {
debugLoc("Step %d: r2: %d, d2: %d\n",
cntr + 1, r2Loc, d2Loc);
// see if we are at the same spot
if (r2Loc == d2Loc) {
result.setMet(true).setStep(cntr + 1).setLoc(r2Loc);
break;
}
// get the location where going; it is the offset
// given in the sequence from the current loc
r2Loc = seq[r2Loc];
d2Loc = seq[d2Loc];
debugLoc("r2 moving to %d; d2 moving to %d\n",
r2Loc, d2Loc);
++cntr;
} //while
return result;
}
类只跟踪结果。省略了getters / setters:
Result
根据样本输入数据,获得以下输出:
机器人永远不会见面 机器人永远不会满足 机器人在2次移动后在位置5相遇 机器人永远不会满足 机器人在8次移动后在8号位置相遇
答案 1 :(得分:0)
我不打算深入了解具体的代码细节,因为这确实是一个关于策略的问题,我们可以使用来寻找解决方案。让我们一起潜入:</ p>
始终查看示例数据以获取线索
让我们看看第一个数据集
10
3 4
5 6 8 7 8 1 9 5 4 6
所以我们有十个地点,每个地点都只有一条通往另一个地点的单程路线。从此,我们已经确定了一些事情:即使在最长的路线中,例如2 3 4 5 6 7 8 9 10 1,在十个位置之后,机器人将开始回溯其步骤。
我们能找到问题的界限吗?
轨道中的两个或不同频率(或相同频率)的周期将产生节拍模式。这种节拍模式将通过两种频率的乘积产生所有可能的排列。因此,在这种情况下(十个位置)我们需要模拟的最大循环次数是10 * 10或100.我不认为你会知道这一点,但它会大大减少KevinO的模拟回答知道以这种方式模拟多少步骤。
我们是否需要对数据进行建模或重新建模?
这是我们获得最大收益的地方。让我们简要地重建地图,找出机器人在每个连续房间里开始的去处:
1 5 8 5 (8 5 8 5 ...)
2 6 1 5 8 5 (8 5 ...)
3 8 5 8 (5 8 5 ...)
4 7 9 4 (7 9 4 ...)
5 8 5 (8 5 ...)
6 1 5 8 5 (8 5 ...)
7 9 4 7 (9 4 ...)
8 5 8 (5 8 ...)
9 4 7 9 (4 7 ...)
10 6 1 5 8 5 (8 5 ...)
注意什么?我做了:
1 5 8 5 (8 5 8 5 ...)
2 6 1 5 8 5 (8 5 ...)
3 8 5 8 (5 8 5 ...)
5 8 5 (8 5 ...)
6 1 5 8 5 (8 5 ...)
8 5 8 (5 8 ...)
10 6 1 5 8 5 (8 5 ...)
----------------------
4 7 9 4 (7 9 4 ...)
7 9 4 7 (9 4 ...)
9 4 7 9 (4 7 ...)
在此示例中,有两个完全独立的曲目。他们永远不会碰。因此,如果你将一个机器人置于3,那么它将会被8-5循环捕获;如果你把另一个放在4,它会被7-9-4循环捕获,并且两个触摸都会变得不合适。我强烈怀疑这是练习的真正目标。
所以退后一步,练习描述从一个房间到另一个房间的箭头地图的方式非常类似于有向图。如果他们描述了一个数据结构,你几乎肯定会构建它,并考虑它的优势是否可以用于将难题解决为简单问题。在这种情况下,您构建两个图形,意识到机器人从不同的图形开始,并回复“机器人永远不会见面。”。
从那里开始,图形表示非常有效地模拟,记住你知道你永远不必超过n * n步,其中n是机器人在图中的房间总数