这次作业比较简单,但还是记录一下。

  • problem1:


这题只要算出矩形左上角的坐标即可。

import acm.graphics.*;
import acm.program.*;
import java.awt.*;

public class DrawCenteredRect extends GraphicsProgram {

	/** Size of the centered rect */
	private static final int WIDTH = 350;
	private static final int HEIGHT = 270;

	public void run() {
		GRect rect= new GRect(WIDTH,HEIGHT);
		rect.setFilled(true);
		rect.setColor(Color.BLUE);
		add(rect,(getWidth()-WIDTH)/2.0,(getHeight()-HEIGHT)/2.0);
	}
}

  • problem2:

import acm.program.*;

public class Countdown extends ConsoleProgram {

	/** Count down to 0 from this number */
	private static final int START = 10;

	public void run() {
		for(int i=START;i>0;i--) {
			println(i);
		}
		println("Liftoff");
	}
}
  • problem3:

这题看起来复杂一些,其实也比较简单。定义一个put方法,每次打印一层,物块个数由i控制,起始位置由x,y控制。假设一共要打印n层,从最后一层开始第k层要答应n-k+1个元素,每行打印完之后更新起始坐标即可。

import acm.graphics.*;
import acm.program.*;
import java.awt.*;

public class Pyramid extends GraphicsProgram {

/** Width of each brick in pixels */
	private static final int BRICK_WIDTH = 30;

/** Height of each brick in pixels */
	private static final int BRICK_HEIGHT = 12;

/** Number of bricks in the base of the pyramid */
	private static final int BRICKS_IN_BASE = 3;

	public void run() {
		double x=(getWidth()-BRICKS_IN_BASE *BRICK_WIDTH)/2.0;
		double y=getHeight()-BRICK_WIDTH;
		int flag=BRICKS_IN_BASE%2;
		for (int i=BRICKS_IN_BASE;i>0;i--) {
			put(i,x,y);
			x+=0.5*BRICK_WIDTH;
			y-=BRICK_HEIGHT;
		}
	}

	public void put(int i,double x,double y) {
		for (int j=0;j<i;j++) {
			GRect rect=new GRect(BRICK_WIDTH,BRICK_HEIGHT);
			add(rect,x+j*BRICK_WIDTH,y);
		}
	}
}
  • problem4:


这题用的方法不大好,是画一个圆弧再填充颜色,应该直接画一个圆就行了。思路是先画最大的红圆,再画中间的白圆,最后画最小的红圆,注意这种画法的起始点是圆外接正方形左上角的定点坐标。

import acm.graphics.*;
import acm.program.*;
import java.awt.*;

public class Target extends GraphicsProgram {	
	public void run() {
		double r1=72;
		double r2=72*0.65;
		double r3=72*0.3;
		double x=getWidth()/2.0;
		double y=getHeight()/2.0;
		double x1=x-r1/2;
		double y1=y-r1/2;
		double x2=x-r2/2;
		double y2=y-r2/2;
		double x3=x-r3/2;
		double y3=y-r3/2;
		draw(x1,y1,r1,1);
		draw(x2,y2,r2,0);
		draw(x3,y3,r3,1);	
	}
	
	public void draw(double x,double y,double r,int flag) {
		GArc s=new GArc(r,r,0,360);
		if (flag==1) {
			s.setFilled(true);
			s.setColor(Color.red);
			add(s,x,y);
		}else {
			s.setFilled(true);
			s.setColor(Color.white);
			add(s,x,y);
		}
	}
}
  • problem5:

这题我的思路是定义一个draw方法画框,write方法画label,这两个方法传入的参数都是每个框的左上角坐标,注意write方法要确定label的起始位置需要知道label的长宽。定义完这两个方法后,运用循环可以完成作业。

import acm.graphics.*;
import acm.program.*;
import java.awt.*;

public class CS106ATiles extends GraphicsProgram {

	/** Amount of space (in pixels) between tiles */
	private static final int TILE_SPACE = 50;
	private static final int TILE_WIDTH = 100;
	private static final int TILE_HEIGHT = 50;

	public void run() {
		double x=getWidth()/2.0-TILE_WIDTH-TILE_SPACE/2.0;
		double y=getHeight()/2.0-TILE_HEIGHT-TILE_SPACE/2.0;
		for (int i=0;i<2;i++) {
			for (int j=0;j<2;j++) {
				double x1=x+i*(TILE_SPACE+TILE_WIDTH);
				double y1=y+j*(TILE_SPACE+TILE_HEIGHT);
				draw(x1,y1);
				write(x1,y1);
			}
		}
	}

	public void draw(double x,double y) {
		GRect rect=new GRect(TILE_WIDTH,TILE_HEIGHT);
		add(rect,x,y);
	}

	public void write(double x,double y) {
		GLabel label =new GLabel("CS106A");
		double a=label.getWidth();
		double b=label.getHeight();
		add(label,x+TILE_WIDTH/2.0-a/2.0,y+TILE_HEIGHT/2.0+b/2.0);
	}
}
  • problem 6

import acm.program.*;

public class PythagoreanTheorem extends ConsoleProgram {
	public void run() {
		println("Enter values to compute the Pythagorean theorem.");
		double a=readDouble("a: ");
		double b=readDouble("b: ");
		double c=Math.sqrt(a*a+b*b);
		println("c = "+c);
	}
}
  • problem 7

这题也是挺简单的,只要注意几个细节即可,一是如果用户输入的第一个数为0,则直接结束,要告诉用户没有输入数字,二是由于不知道输入范围,所以先要记录第一个输入的数,将其赋值给small和large。

import acm.program.*;

public class FindRange extends ConsoleProgram {
	public void run() {
		println("This program finds the largest and smallest numbers.");
		int a=readInt("?");
		if(a==0) {
			println("No values have been entered.");
		}else {
			int large=a;
			int small=a;
			while(true) {
				if(a==0) {
					break;
				}
				a=readInt("?");
				if (a>large) {
					large=a;
				}
				if (a<small) {
					small=a;
				}
			}
			println("smallest: "+small);
			println("largest: "+large);
		}
	}
}
  • problem 8

这个是著名的冰雹猜想,输入一个正整数,偶数除以2,奇数乘以3加1,最后总能变成1。看着很简单,但是至今无人证明出来。本题要按规则打印出来即可。

import acm.program.*;

public class Hailstone extends ConsoleProgram {
	public void run() {
		int a=readInt("Enter a number: ");
		int i=0;
		while(a!=1) {
			if (a%2==1) {
				println(a+" is odd,so I make 3n+1: "+(3*a+1));
				a=3*a+1;
			}else {
				println(a+" is even,so I take half: "+a/2);
				a/=2;
			}
			i++;
		}
		println("The process took "+i+" to reach 1");
	}
}