本题主要考察算法设计。编写程序,让卡雷尔在第一行的中央放置一个灰色方块。比如,假
设卡雷尔从下图所示的位置开始行动:

最终卡雷尔应该站在灰色方块上,位置如下:

注:程序执行结束时界面上应当只有一个灰色方块,位于第一行的中间位置,在程序执行过
程中卡雷尔可以随意摆放方块,但在结束前必须把它们全部拾起。
解决本题,你可以参考如下信息:
卡雷尔的起始位置是第一列第一行,面朝东,携带了无限的灰色方块;
界面在初始状态下没有任何内墙或灰色方块;
界面不一定是正方形,但你可以假设它的长宽相等。
你还可以参考如下信息简化过程:
如果界面的宽是奇数,卡雷尔必须把灰色方块放置在中间的位置;如果是偶数,卡雷尔
可以把灰色方块放在中间的两个位置中的任意一个。
程序运行结束时卡雷尔的朝向不作要求。
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();
}
}
}
本文介绍了一种使用Karel程序解决在网格中找到并放置一个灰色方块于中间位置的方法。程序确保无论网格大小为奇数或偶数,方块都能准确放置在中间位置。Karel从第一行第一列出发,面向东,携带无限数量的灰色方块。
201

被折叠的 条评论
为什么被折叠?



