斯坦福CS106A作业2

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

  • problem1:


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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个元素,每行打印完之后更新起始坐标即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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:


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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的长宽。定义完这两个方法后,运用循环可以完成作业。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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

1
2
3
4
5
6
7
8
9
10
11
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。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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。看着很简单,但是至今无人证明出来。本题要按规则打印出来即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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");
}
}