本题主要考察算法设计。编写程序,让卡雷尔在第一行的中央放置一个灰色方块。比如,假
设卡雷尔从下图所示的位置开始行动:
最终卡雷尔应该站在灰色方块上,位置如下:
注:程序执行结束时界面上应当只有一个灰色方块,位于第一行的中间位置,在程序执行过
程中卡雷尔可以随意摆放方块,但在结束前必须把它们全部拾起。
解决本题,你可以参考如下信息:
卡雷尔的起始位置是第一列第一行,面朝东,携带了无限的灰色方块;
界面在初始状态下没有任何内墙或灰色方块;
界面不一定是正方形,但你可以假设它的长宽相等。
你还可以参考如下信息简化过程:
如果界面的宽是奇数,卡雷尔必须把灰色方块放置在中间的位置;如果是偶数,卡雷尔
可以把灰色方块放在中间的两个位置中的任意一个。
程序运行结束时卡雷尔的朝向不作要求。
code:
import stanford.karel.*;
public class MidpointFindingKarel extends SuperKarel {
public void run(){
if(frontIsBlocked()){
putBeeper();
}else{
findMidpoint();
checkEvenLandPutR(); //若为偶数长度可以选择放在左边或者右边
}
}
public void findMidpoint(){
while(noBeepersPresent()){
putTwoBeepers();
back();
pickBeeper();
if(noBeepersPresent()){
putBeeper();
move();
}
}
}
//放2个Beeper,同时清除上一轮的标记Beeper
public void putTwoBeepers(){
turnAround();
if(frontIsClear()){
move();
pickBeeper();
turnAround();
move();
putBeeper();
}else{
turnAround();
putBeeper();
}
move();
while(frontIsClear() && noBeepersPresent()){
move();
}
//因Beeper而停下的情况
if(beepersPresent()){
pickBeeper();
turnAround();
move();
putBeeper();
turnAround();
}else{
putBeeper(); //第一轮面对墙的情况
}
}
//回去
public void back(){
turnAround();
move();
while(noBeepersPresent() && frontIsClear()){
move();
}
if(frontIsBlocked() && noBeepersPresent()){
turnAround();
while(noBeepersPresent()){
move();
}
}
turnAround();
}
//检测长度是否为偶数的地图,若是则将方块置于右边
public void checkEvenLandPutR(){
if(facingEast()){
turnAround();
}
move();
if(beepersPresent()){
pickBeeper();
}
turnAround();
move();
}
//检测长度是否为偶数的地图,若是则将方块置于左边
public void checkEvenLandPutL(){
if(facingEast()){
turnAround();
}
move();
if(beepersPresent()){
turnAround();
move();
pickBeeper();
turnAround();
move();
}else{
turnAround();
move();
}
}
}