您的位置:首页 > 编程语言

斯坦福大学开放课程——编程方法 作业1-4 (附作业中文翻译及源码)【在中心点放置Beeper】

2011-01-30 21:57 656 查看
Problem 4

As an exercise in solving algorithmic problems, program Karel to
place a single beeper at the center of 1st Street. For example, if Karel
starts in the world



it should end with Karel standing on a beeper in the following position:

Note that the final configuration of the world should have only a
single beeper at the midpoint of 1st Street. Along the way, Karel is
allowed to place additional beepers wherever it wants to, but must pick
them all up again before it finishes.

In solving this problem, you may count on the following facts about the world:

Karel starts at 1st Avenue and 1st Street, facing east, with an infinite number of beepers in its bag.

The initial state of the world includes no interior walls or beepers.

The world need not be square, but you may assume that it is at least as tall as it is wide.

Your program, moreover, can assume the following simplifications:

If the width of the world is odd, Karel must put the beeper in the
center square. If the width is even, Karel may drop the beeper on either
of the two center squares.

It does not matter which direction Karel is facing at the end of the run.

There are many different algorithms you can use to solve this
problem. The interesting part of this assignment is to come up with a
strategy that works.

****************翻译分割线***************

习题四:

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



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



注:程序执行结束时界面上应当只有一个灰色方块,位于第一行的中间位置,在程序执行过程中卡雷尔可以随意摆放方块,但在结束前必须把它们全部拾起。解决本题,你可以参考如下信息:

1、卡雷尔的起始位置是第一列第一行,面朝东,携带了无限的灰色方块;

2、界面在初始状态下没有任何内墙或灰色方块;

3、界面不一定是正方形,但你可以假设它的长宽相等。

你还可以参考如下信息简化过程:

1、如果界面的宽是奇数,卡雷尔必须把灰色方块放置在中间的位置;如果是偶数,卡雷尔可以把灰色方块放在中间的两个位置中的任意一个。

2、程序运行结束时卡雷尔的朝向不作要求。

解决这道题的算法很多,找出一个解决方法是本题的乐趣所在。

/*本程序没有使用赋值
执行需要的条件及达到的目的如下:
条件
1:卡尔有无限Beeper
2:第一街:第二街是空的,并且街道长度≥3
达到的目的
1:如果街道长度是奇数,雷卡尔(karel)最终会仅在第一街的中心点放置Beeper
2:如果街道长度是偶数,雷卡尔(karel)最终会放置一个Beeper在中间2个位置的任意一个。*/

import stanford.karel.*;
public class put_middle_on_first_street extends SuperKarel {
public void run (){
//第一步:先把两端的Beeper填充掉,并回到第一街原始点前一个空白处
putBothEndBeeper();
//第二步:使用上面的方法,逐渐从两边向中间填充,填充掉最后一个,在那上方放一个
putBeepeAboveMiddle();
//第三步:回到第一街原始点
moveToFirstStreetStartPoint();
//第四步:把第一街所有Beeper捡起来
cllectFirstStreet();
//第五步:第二街把Beeper向下移一行,即放在第一街中心点。完工。
putMiddleOnFirstStreet();
}
//第一步
private void putBothEndBeeper(){
putBeeper();
moveToWall();
turnAround();
putBeeper();
moveToWall();
turnAround();
move();
move();
}
//第二步
private void putBeepeAboveMiddle(){
while(noBeepersPresent()){
moveToOppositeBlank();
}
/*最中心的位置两边都会逐渐填充掉,当卡尔填充最中心的位置后,
* 因为“惯性”,会跑到最中心的左边或者右边去。让卡尔转身,退一格
*/
turnAround();
move();
turnRight();
//如果面向墙,就转身去第二街放一个;如果不是,就直接去第二街放一个
if(frontIsBlocked()){
turnAround();
move();
putBeeper();
}else{
move();
putBeeper();
}
}
//第三步
private void moveToFirstStreetStartPoint(){
turnLeft();
moveToWall();
turnLeft();
move();
turnLeft();
}
//第四步
private void cllectFirstStreet(){
while (frontIsClear()){
pickBeeper();
move();
//如果最中间没有Beeper,下述语句可让卡尔继续去收其他的Beeper
if(noBeepersPresent()){
move();
}
}
pickBeeper();
}
//第五步
private void putMiddleOnFirstStreet(){
turnLeft();
move();
turnLeft();
while (noBeepersPresent()){
move();
}
pickBeeper();
turnLeft();
move();
putBeeper();
}
//让卡尔去最远的空位置放置Beeper
private void moveToOppositeBlank(){
while(noBeepersPresent()){
move();
}
turnAround();
move();
putBeeper();
move();
}
private void moveToWall(){
while(frontIsClear()){
move();
}
}
}


**************分割线*****************

没有使用赋值,如果使用赋值语句的话代码应该会简化很多。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: