我在一家IT公司的编程测试中得到了这个问题。 我会尽力解释它。
问题如下:
给定一个原点(0,0)的Ant,它只在给定的路径数组上以顺时针方向(仅右转)移动。所以例如如果路径数组是{2,3,4,5,7},则蚂蚁向左移动2个单位,然后向下移动3个单位,然后向右移动4个单位,然后向上移动5个单位然后向下移动7个单位等等。
所以编写一个显示蚂蚁最终位置(坐标)的代码,并说明如果蚂蚁以下列格式与其路径相交:
Ant:(x1,y1):(是/否)
例如: (1)array = {1,6,3,5,4} 输出:Ant:(2,-1):是
以图形方式显示
(0, 0)__(1,0)
|
(-2,-1) __ __ __ __(2,-1)
| |
| |
| |
| |
| |
(-2,-6) __ __ __ (1,-6)
这里蚂蚁的路径在(1,-1)
处相交(2)array = {2,2,2,1} 输出:Ant:(0,-1):否
以图形方式显示
(0, 0)__ __(2,0)
.(0,-1) |
| |
(0,-2)__ __(2,-2)
这里的蚂蚁不会与它的路径相交。
我写了一个代码来找到最终位置:
public class Ant {
static void findAnt(int arr[])
{
int count = 0;
int x=0,y=0;
for(int element: arr){
if(count>3)
count = 0;
switch(count++){
case 0: x=x+element;
break;
case 1: y=y-element;
break;
case 2: x=x-element;
break;
case 3: y=y+element;
break;
}
}
System.out.println("Ant: "+x+" "+y);
}
public static void main(String[] args)
{
int arr[] = new int[]{2,2,2,1};
findAnt(arr);
}
}
但是我不能设计一个算法来显示蚂蚁是否相交。 请指教。
答案 0 :(得分:1)
arr[1] <= arr[3]
如果arr[0] <= arr[2]
只需要检查这些位置,它将水平相交。
for (int i = 0; i < arr.length; i++){
if (i == arr.length-2)
return false;//prevents indexoutofbounds
if (arr[i] <= arr[i+2])
return true;//intersects
}
这应该检查p0是否小于p2,p1,是否小于p3,p2是否小于p4,依此类推。
boolean intersect = false;
for (int i = 0; i < arr.length; i++){
if (arr[i] == arr[arr.length-2]){//i changed this
intersect = false;//prevents indexoutofbounds
break;
}
if (arr[i] <= arr[i+2])
intersect = true;//intersects
break;
}
然后打印出交叉
答案 1 :(得分:1)
一种不在内存中保留网格的解决方案是在内存中保留一组访问位置。这样做的好处是,您无需事先知道蚂蚁潜在路径的边界。是否需要比网格更多或更少的内存,取决于网格的大小,以及蚂蚁旅程的长度。
public class VisitedTileLog {
Set visitedTiles = new HashSet<Coordinates>();
boolean hasIntersected = false;
public void logVisit(Coordinates c) {
if(! visitedTiles.add(c)) {
hasIntersected = true;
}
}
public boolean hasIntersected() {
return hasIntersected;
}
}
当然,您需要Coordinates
课程equals()
和hashCode()
:
public class Coordinates {
private int x,y;
public Coordinates(int x, int y) {
this.x = x;
this.y = y;
}
public boolean equals(Object o) {
// Let your IDE write this, or read up on best practice.
}
public int hashCode() {
// Let your IDE write this, or read up on best practice.
}
// Examples of other methods this might have...
public int getX() { ... }
public int getY() { ... }
public Coordinates move(int distance, Direction direction);
}
现在你可以带着你的蚂蚁散步,每次移动时都要更新hasIntersected
:
VisitedTileLog log = new VisitedTileLog();
for(int distance : distances) {
...
log.logVisit(...);
...
}
可以通过记录整个步骤的便捷方法来增强此类 - logVisit(Coordinates from, Coordinates to)
或logVisit(Coordinates start, int distance, CompassPoint direction)
。
根据面试官的不同,这样的解决方案可能会因为面向对象而获得额外的荣誉。实际上,如果它还保持currentPosition
字段,则可以增强此类以解决整个问题。
答案 2 :(得分:0)
实现此目的的一种方法是在每次移动期间绘制线条以供参考。并且在每次移动之前检查它是否遇到已经绘制的相同坐标。以下是此方法的代码。你绝对可以对它进行微调,但这是解决问题的一种方法。
步骤:
创建Coordinate
类型以存储坐标
创建可以容纳的Ant
:
current coordinate
:这将随时保存Ant当前坐标
Direction to Move next
:向右,向左,向上或向下
数据集以跟踪traversed coordinate
保存所有coordinates that are revisited
现在,在ant
的每次移动中,它知道接下来要移动的方向。在每次移动中,我们绘制当前坐标和终点之间的所有坐标,并将它们存储在遍历坐标set
中。如果有点击,我们会将其存储在相交的坐标set
中。
最后,current coordinate
的{{1}}为我们提供了最终ant
,如果相交的coordinate
为set
这是长代码,我认为它正常工作。
not empty.
}
答案 3 :(得分:-1)
问题很难确定它是否与之前的路径相交。我创建一个布尔值来记录它是否增加了圆圈。如果它总是增加,它将不会与先前的路径相交。如果它变为递减,一旦它再次开始增加,它将与路径相交。否则,它将不会与路径
相交def ant(arr):
length = len(arr)
x = sum(arr[::4]) - sum(arr[2:][::4])
y = sum(arr[3:][::4]) - sum(arr[1:][::4])
if length < 4:
return x, y, False
t1, (t2, t3, t4) = 0, arr[:3]
increase = (t2 < t4)
for i in xrange(3, length):
t5 = arr[i]
if increase and t3 >= t5:
if t1 + t5 - t3 < 0 or i+1 < length and arr[i+1] + t2 - t4 < 0:
increase = False
elif i + 1 < length:
return x, y, True
elif not increase and t3 <= t5:
return x, y, True
t1, t2, t3, t4 = t2, t3, t4, t5
return x, y, False