斯坦福大学开放课程——编程方法 作业1-4 (只解决奇数宽度的算法)【在中心点放置Beeper】

本文介绍了一种使用Karel在第一行中央放置标记的算法。该算法能在任何宽度的地图上找到中点,无论其为奇数或偶数。通过在两端放置标记并逐步向中间逼近的方式实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面的中文翻译是引用,出自:http://blog.youkuaiyun.com/goodpress/article/details/6170386

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、程序运行结束时卡雷尔的朝向不作要求。
解决这道题的算法很多,找出一个解决方法是本题的乐趣所在。

/*******************************引用结束****************************************/

/*
 * File:MidpointFingingKarel_2a.java
 * -----------------------------
 * 利用别人的算法自己写的程序,策略是先在两头放上Beeper然后分别向中间逼进
 */
import stanford.karel.*;

public class MidpointFingingKarel_2a extends SuperKarel {
	public void run(){
		putBeeperBothEnds();
		moveBeepers();
	}
	// 在两端放上beeper
	private void putBeeperBothEnds(){
		putBeeper();
		moveToWall();
		putBeeper();
		turnAround();
	}
	// 移动到墙
	private void moveToWall(){
		while (frontIsClear()){
			move();
		}
	}
	// 移动beeper直到下个空位有beeper然后向北移动一步
	private void moveBeepers(){
		while (notFacingNorth()){
			moveOneStep();
		}
	}
	// 把最左右两边的beeper向前移动一步
	private void moveOneStep(){
			if (beepersPresent()){
				pickBeeper();
				move();
				if (noBeepersPresent()){
					putBeeper();
					move();
					findBeeper();
					turnAround();
				} else {
					faceNorth();
					move();
				}
				
			}
	}

	// 向北
	private void faceNorth(){
		while (notFacingNorth()){
			turnLeft();
		}
	}
	// 寻找Beeper
	private void findBeeper(){
		while (noBeepersPresent()){
			move();
		}
	}
}


/**********************************分割线********************************************/
看了别人的算法自己写的程序。但只有在奇数宽度下才能正确找到中点。完美解决请看 :斯坦福大学开放课程——编程方法 作业1-4 (完美解决任何地图都能找到中点)【在中心点放置Beeper】
同样的算法还有:(引用自:[斯坦福开放课程.编程方法].作业.1-4.Karel将Beeper放在中间)

/*
 * File: MidpointFindingKarel.java
 * -------------------------------
 * When you finish writing it, the MidpointFindingKarel class should
 * leave a beeper on the corner closest to the center of 1st Street
 * (or either of the two central corners if 1st Street has an even
 * number of corners).  Karel can put down additional beepers as it
 * looks for the midpoint, but must pick them up again before it
 * stops.  The world may be of any size, but you are allowed to
 * assume that it is at least as tall as it is wide.
 */
import stanford.karel.*;
public class MidpointFindingKarel extends SuperKarel {
	public void run()
	{
		/*first 2 beepers*/
		putBeeper();
		while(frontIsClear())
		{
			move();
		}
		turnAround();
		putBeeper();
		/*put a beeper in the mid of th 1st street*/
		while(beepersPresent())
		{
			move();
			while(noBeepersPresent())
			{
				move();
			}
			turnAround();
			pickBeeper();
			move();
			if(noBeepersPresent())
			{
				putBeeper();
			}else
			{
				while(notFacingNorth())
				{
					turnRight();
				}
				move();
			}
			
		}
	}
		
}





                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值