├── 从0开始的CS61b生活 V1.pdf
├── A Guide For CS 61A_ Structure and Interpretatiof Computer Programs.pdf
├── cs61a问题集锦.md
├── 评价.md
├── HelloWorld.java
├── week1.md
├── 1-autograder配置.md
├── README.md
├── proj0.md
├── scope-modifier.md
└── week2.md
/从0开始的CS61b生活 V1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SFUMECJF/cs61b-study-guide/HEAD/从0开始的CS61b生活 V1.pdf
--------------------------------------------------------------------------------
/A Guide For CS 61A_ Structure and Interpretatiof Computer Programs.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SFUMECJF/cs61b-study-guide/HEAD/A Guide For CS 61A_ Structure and Interpretatiof Computer Programs.pdf
--------------------------------------------------------------------------------
/cs61a问题集锦.md:
--------------------------------------------------------------------------------
1 |
2 | ## 1. 怎么学?
3 | 直接学就行。看textbook,或者视频该不该看,因人而异。反正lab和hw等作业是最重要的,一定要做。
4 |
5 | ## 2. 注册自动测试
6 | 下面的情况是因为学校没有选择伯克利
7 | 
8 |
--------------------------------------------------------------------------------
/评价.md:
--------------------------------------------------------------------------------
1 | 课号/课程名/学习主页:[cs61b2018SPring](https://sp18.datastructur.es/)
2 |
3 | 教授:XX
4 |
5 | 贡献者:XX
6 |
7 | [视频]()
8 |
9 | [autograder设置]()
10 |
11 | 课程评价:学了一定不会后悔的课程,也许有其他很好的课,但是cs61b的学习人数以及课程质量一定不会差。
12 |
13 | - 优点:
14 | - 课程lab/HW/Project任务多而指导详细(也许是缺点)
15 | - 所有资料都在网上并且和本校学生一模一样
16 | - 从小的数据结构开始填充,便于理解
17 |
18 | - 缺点:
19 | - 有些guide的讨论或者问题没有答案
20 |
21 | 学习建议:[2018年的主页](https://sp18.datastructur.es/) 据课程表学习。辅助阅读在线教材,看了视频可以不看教材文字。英语好看[bilibili视频]()
22 |
23 | 组队群:QQ9132236113 [微信](https://github.com/SFUMECJF/cs61b-study-guide)
24 |
25 | 其他笔记链接:[XXX]()
--------------------------------------------------------------------------------
/HelloWorld.java:
--------------------------------------------------------------------------------
1 | public class HelloWorld {
2 | public static void main(String[] args) {
3 | String name = "Hello rererewr德国模样 world!";
4 | System.out.println(name);
5 | }
6 | }
7 |
8 | public class Puppy{
9 | public Puppy(){
10 | name = "大黄";
11 | }
12 |
13 | public Puppy(String name){
14 | // 这个构造器仅有一个参数:name
15 | this.name = name;
16 | }
17 | public Puppy(String name, int age){
18 | // 这个构造器仅有一个参数:name
19 | this.name = name;
20 | }
21 | }
22 |
23 | da_huang = Puppy();
24 | da_huang = Puppy("大红");
--------------------------------------------------------------------------------
/week1.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## 1.2
4 |
5 | ### exercise
6 |
7 | #### C-2
8 |
9 | 
10 |
11 | #### B-1
12 |
13 | 没有error用T代表的话,则TTFFT
14 |
15 | ### Discission
16 |
17 | 关于最后一题,
18 |
19 | 3 Writing Your First Program
20 |
21 | 两种形式写斐波娜砌数列:
22 |
23 | ```java
24 | public static int fib(int n) {
25 | if (n <= 1) {
26 | return n;
27 | } else {
28 | return fib(n - 1) + fib(n - 2);
29 | }
30 | }
31 | ```
32 |
33 | 第一种方法是很常见的一种写法,只要做大量的递归的习题,就可以想到。就是指定想要的状态,从这个状态一直倒退到基线的感觉。
34 |
35 | 第二种方法比较少见,将相加和迭代的运算作为一个表达式放到`fib2(n, k + 1, f1, f0 + f1);`函数的参数里了,另外是从基线往上运算的感觉。
36 |
37 | ```java
38 | public static int fib2(int n, int k, int f0, int f1) {
39 | if (n == k) {
40 | return f0;
41 | } else {
42 | return fib2(n, k + 1, f1, f0 + f1);
43 | }
44 | }
45 | ```
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/1-autograder配置.md:
--------------------------------------------------------------------------------
1 | 之前发过一篇召集学习队友的文章,一起学习伯克利大学的Java数据结构课程。最近也到了总结的时候。
2 |
3 |
4 |
5 | ## autograder使用
6 |
7 | 设置好autograder,我们就可以自己写作业并查看反馈了。
8 |
9 | 首先在这里说一下原理,知乎上有一些回答可以作为参考。
10 |
11 | [知乎参考1](https://zhuanlan.zhihu.com/p/115229260)
12 |
13 | [知乎参考2](https://www.zhihu.com/search?type=content&q=autograder)
14 |
15 | 首先,你自己建一个仓库,这个仓库的名字叫什么无所谓,关键是仓库内部需要有规定好的文件夹的框架(这个框架就是课程的专属github),文件的组织顺序(如果你自己想多写几个README啥的,对评分没有影响的)。我们要做的就是填好对应的文件里的内容,然后在自动评分网站和我们的仓库关联,网站就可以找到对应的文件来评分。
16 |
17 | 分为2步:
18 | 1. 在github上注册自己的仓库,并下载别人写好的代码框架。如果是熟练使用git的老鸟,其实就是把`https://github.com/Berkeley-CS61B/skeleton-sp18.git`内容放到自己建的一个仓库里即可。
19 | - 如何在github上建一个空仓库,并且把空仓库下载到本地。这部分建议上网搜索。
20 |
21 |
22 |
23 | - 假设你的仓库名字叫做`cs61b`,那么右键`git bash`打开这个文件夹。
24 |
25 |
26 |
27 | - 依次输入以下指令:
28 | `git remote add skeleton https://github.com/Berkeley-CS61B/skeleton-sp18.git`
29 |
30 | - ` git pull skeleton master --allow-unrelated-histories`
31 | `git push -u origin main`
32 |
33 | - 做完这些,在github的网页上你可以看到多了很多文件夹。
34 | 2. 在[gradescope.com](https://gradescope.com/)网站上注册自己的账号,关联github,写好代码后,提交到github上,到网站上查看分数。
35 | 点击对应的lab,按照指示选择自己的仓库名字等,就会评分了。
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # cs61b开工指南
4 |
5 | ## 更新!!!
6 | 群友推出了完整的cs61a和cs61b的使用指南!欢迎大家提意见。
7 | 感谢糸和月色成笺写的课程食用教程:
8 | 61A
9 | [谷歌文档食用cs61a教程](https://docs.google.com/document/d/1pceaNK3_1mcFOPtK47YKqDl45u8kWCzayuVxP9mrWZg/edit?usp=sharing)
10 | 61B
11 | [谷歌文档食用cs61b教程](https://docs.google.com/document/d/1lh1GyJfP4d99Kd2ubFWcHtzMgwW4M3aMDLqafMCGO7I/edit?usp=sharing)
12 |
13 | 这两位群友的文档是共享文档,为防止恶意编辑,本仓库对两份文档做了备份。大家也可在这里查看:[61a备份2022-03-20](https://github.com/SFUMECJF/cs61b-study-guide/blob/main/A%20Guide%20For%20CS%2061A_%20Structure%20and%20Interpretatiof%20Computer%20Programs.pdf) [61b备份2-22-3-20](https://github.com/SFUMECJF/cs61b-study-guide/blob/main/A%20Guide%20For%20CS%2061A_%20Structure%20and%20Interpretatiof%20Computer%20Programs.pdf)
14 |
15 |
16 | ## 1 为什么要学习cs61b
17 |
18 | 补计算机基础,数据结构只是其中之一。[名校公开课程评价网](https://github.com/conanhujinming/comments-for-awesome-courses)
19 |
20 | 课程评价:学了一定不会后悔的课程,也许有其他很好的课,但是cs61b的学习人数以及课程质量一定不会差。
21 |
22 | - 优点:
23 | - 课程lab/HW/Project任务多而指导详细(也许是缺点)
24 | - 所有资料都在网上并且和本校学生一模一样
25 | - 从小的数据结构开始填充,便于理解
26 |
27 | - 缺点:
28 | - 有些guide的讨论或者问题没有答案
29 |
30 | ## 学完这门课可以获得什么
31 |
32 | - 设计数据结构,以链表为起点,根据需求把其他的数据结构依次设计出来
33 | - Java基本数据结构
34 | - git基本使用
35 |
36 |
37 |
38 | ## 学习方式
39 |
40 | ### 学习哪一门?
41 | 2021需要下载本地测试
42 |
43 | 推荐学习sp2018
44 |
45 | ### 学习顺序
46 | 只需要在[课程主页](https://sp18.datastructur.es/)学习即可,我们学习18年的,有自动判分系统,和他们本校的学生是一样的。
47 |
48 | 
49 |
50 | 拿第一周举例,上了两次课,分别是1.1和1.2,建议观看顺序是先点击`1 教材和视频`,边看教材文字,边打开里面嵌入的youtube视频,看完这部分,就不需要看video和slides了。直接看`2 guide`对这门课的总结。之后再看这周的下一节课。当所有课程看完后,可以去看`5 discussion`以及`6 lab`和`7 本周的大作业 `。
51 |
52 | 学习顺序大概如上,注意 :做作业并接受反馈是最有效的学习方式,哪怕不看课程,也要去做作业 。不过建议看视频,老师边打代码边讲课,说实话可以观察一下顶尖高手怎么打代码。
53 |
54 | project2可以考虑略过,javafx真的难用.
55 |
56 | ## 本仓库查看顺序
57 |
58 | - week0
59 | - [课程概览]()
60 | - [autograde配置]()
61 | - wee1
62 | - [discussion]()
63 | - [lab]()
64 | - week2
65 | - [discussion]()
66 | - [lab]()
67 | - [proj0]()
68 |
69 |
70 |
71 | ## 一起讨论
72 |
73 | 欢迎有想一起补cs基础的同学加入下方的群聊一起讨论,从数据结构开始从事互联网行业。
74 |
75 | 在qq群里,大家**非常非常非常地活跃**,每天都有很多人在讨论!欢迎入群!
76 | **千万前万别说敏感话题,群已经被封了一次了!!!!**
77 |
78 | qq群:482582963
79 |
80 | 微信群扫码
81 |
82 | 
83 |
--------------------------------------------------------------------------------
/proj0.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | [TOC]
4 |
5 |
6 |
7 | ## 1
8 |
9 | ```shell
10 | .\StdDraw.java:299: 错误: 编码GBK的不可映射字符
11 | * You save your image to a file using the File 鈫? Save menu option.
12 | ^
13 | .\StdDraw.java:433: 错误: 编码GBK的不可映射字符
14 | * from (0.5, 鈥?∞) to (0.5, ∞) may not be visible even in the
15 | ^
16 | .\StdDraw.java:1190: 错误: 编码GBK的不可映射字符
17 | * (xn鈥?1, yn鈥?1).
18 | ^
19 | .\StdDraw.java:1190: 错误: 编码GBK的不可映射字符
20 | * (xn鈥?1, yn鈥?1).
21 | ^
22 | .\StdDraw.java:1219: 错误: 编码GBK的不可映射字符
23 | * (xn鈥?1, yn鈥?1).
24 | ^
25 | .\StdDraw.java:1219: 错误: 编码GBK的不可映射字符
26 | * (xn鈥?1, yn鈥?1).
27 | ^
28 | 6 个错误
29 |
30 | ```
31 |
32 | 解决方案:
33 |
34 | ```shell
35 | javac -encoding utf-8 NBody.java
36 | java NBody 157788000.0 25000.0 data/planets.txt
37 | ```
38 |
39 |
40 |
41 |
42 |
43 | ### 拷贝构造
44 |
45 | `Dog fido = new Dog("Fido", "Poodle", 1);`
46 |
47 | 1. JVM创造空构造函数,分配足够容纳所有变量的空间,但是是默认值。
48 |
49 | 
50 |
51 | 2. JVM执行构造函数
52 |
53 | #### 创造两个构造函数
54 |
55 | ```java
56 | public Dog(String name, String breed, int age) {
57 | System.out.println("_name: " + _name + ", _breed: " + _breed + ", _age: " + _age);
58 | _name = name;
59 | _breed = breed;
60 | _age = age;
61 | }
62 |
63 | public Dog(String name, String breed1, String breed2, int age) {
64 | Dog dog = new Dog(name, breed1 + breed2, age);
65 | }
66 |
67 | // 正确的构造函数
68 | public Dog(String name, String breed1, String breed2, int age) {
69 | this(name, breed1 + breed2, age);
70 | }
71 |
72 | public Dog(String name, String breed1, String breed2, int age) {
73 | _name = name;
74 | _breed = breed1 + breed2;
75 | _age = age;
76 | }
77 |
78 |
79 | // 调用:
80 | Dog tommy = new Dog("Tommy", "Poodle", "Golden Retriever", 1);
81 | ```
82 |
83 |
84 |
85 | 
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | ## 互相交流
94 |
95 |
96 | 读者你好!如果你对本文内容感兴趣,我十分希望能够和你互相学习,可以扫码和我联系!一起进步
97 |
98 |
99 |
100 | 
101 |
102 |
--------------------------------------------------------------------------------
/scope-modifier.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | [TOC]
4 |
5 | ## 0 代码框架
6 |
7 | 使用一个代码工程,完成对域和修饰符的学习
8 |
9 | ```tree
10 | -SF_exercise
11 | -ClassMain.java
12 | -Scope.java
13 | ```
14 |
15 | 在一个`SF_exercise`文件夹里有两个文件,其中ClassMain.java里执行主函数,Scope.java是为了学习而制造的其他类。
16 |
17 | ## 1 static and non-static
18 |
19 | static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法
20 |
21 | ### 1.1 对于类
22 |
23 | static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法。
24 |
25 | 显然,只有一个类的成员可以用static来修饰。那么,对于我们的代码,显然`Scope.java`里的`Scope`类和`ClassMain.java`类里的`ClassMain`类前面,都不可以有这个修饰符。
26 |
27 | #### 类中的类
28 |
29 | 可以将一个类的定义放在另一个类的内部定义,这样的类就被称为嵌套类,包含嵌套类的类被称为外部类(outer class),也可以叫做封闭类。
30 |
31 | 嵌套类可以分为两种:
32 |
33 | - 静态嵌套类(Static Nested Classes):使用static声明,一般称为嵌套类(Nested Classes);
34 | - 非静态嵌套类(Non-static Nested Classes):非static声明,一般称为内部类(Inner Classes);
35 |
36 | 嵌套类是它的外部类的成员。`非静态嵌套类(内部类)可以访问外部类的其他成员,即使该成员是私有的,而静态嵌套类只能访问外部类的静态成员。`
37 |
38 |
39 | ### 1.2 类中的方法
40 |
41 | 类中的数据也就是属性,可以设置为`static`和`no static`,根据我们代码的结构完成理解:
42 |
43 | #### `ClassMain.java`
44 |
45 | ```java
46 | public class ClassMain {
47 |
48 | public static void main(String[] args) {
49 | Scope poppa = new Scope();
50 | poppa.bark();
51 | Scope.bark();//会报错
52 | poppa.runFast();
53 | Scope.runFast();
54 | }
55 | }
56 | ```
57 |
58 | #### `Scope.java`
59 |
60 | ```java
61 | public class Scope{
62 | static int only_one = 1;
63 | int maybe_many = 12;
64 | public void bark(){
65 | System.out.println("Moo");
66 | }
67 | public static void runFast(){
68 | System.out.println("Ruff Run");
69 | }
70 | }
71 | ```
72 |
73 | 在主函数中,外部类Scope和Scope的实体都可以调用`static`的成员方法,不会报错。但是一般情况下,类调用static,实体调用non-static,只是如果实体调用static,也可以,语法允许。
74 |
75 | 但是,只有实体可以调用non-static,类调用non-static会报错。
76 |
77 | 这是为什么呢?
78 |
79 | static是静态修饰符:
80 | 什么叫静态修饰符呢?大家都知道,在程序中任何变量或者代码都是在编译时由系统自动分配内存来存储的,`而所谓静态就是指在编译后所分配的内存会一直存在,直到程序退出内存才会释放这个空间,也就是只要程序在运行,那么这块内存就会一直存在。`
81 |
82 | 也就是说,static在编译的时候分配内存,存在这个static的东西,所以实体和类都可以调用它,但是non-static的东西,没有在编译的时候分配内存,所以需要先生成一个实体,实体里含有这个non-static的东西,再通过实体调用。
83 |
84 | ### 1.3 类中的属性
85 |
86 | 基本和方法差不多,不过这里要注意。
87 |
88 | 如果一个属性是static,那个,不管创建了多少个实体,比方说,上面的代码,` static int only_one = 1; int maybe_many = 12;`
89 |
90 | 不管创建了多少个实体,` static int only_one`不会重复创建到实体里,只会有一个内存,放这个变量的值,当类和实体去调用only_one 的时候,整个代码,都会访问到这一个变量。only_one 不属性任何一个实体,就是放到一旁,每个类和实体都可以访问它。
91 |
92 | 而每创建一个实体,`int maybe_many`都会被重复创建,每个实体里都有一个`int maybe_many`.
93 |
94 | ## 2 public private and protected
95 |
96 | 这里就是说,一个变量和方法前面,加上范围修饰符后,什么其他的方法可以访问这些他们呢?一张图解决,这里需要去理解包,以及包内类的概念。
97 |
98 | 比如,我在`Scope.java`和`ClassMain.java`代码里最上一行,加上`package SF_exercise;`表示,这两个函数在一个包内,这个包就是SF_exercise文件夹,这两个类就是同一个包的类。
99 |
100 | [官方教程](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
101 |
102 | 
103 |
104 |
105 |
106 | ## 互相交流
107 |
108 | 欢迎大家一起加好友学习!
109 | 公众号名称:三丰杂货铺
110 |
111 |
112 |
113 | 
114 |
115 |
--------------------------------------------------------------------------------
/week2.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | [TOC]
4 |
5 | 关于scope的理解,类内部的数据和函数:public和protected,private
6 |
7 | static和no-static
8 |
9 | 对于类内部的类,这两个关系:
10 |
11 | ## 1 discussion
12 |
13 | 第一题那个this到底怎么理解?
14 |
15 | 如果两个属性都是static的,那么实例的属性和static前期是一样的嘛?
16 |
17 | 下方的代码,我们可以知道:如果类内部的属性都是static,那么只有一块地址是储存这两个变量的,无论多少个实例,无论通过类还是实例调用它,都会是同一个变量。
18 |
19 | ```java
20 | public class Shock {
21 | public static int bang;
22 | public static Shock baby;
23 | public Shock() {
24 | this.bang = 100;
25 | }
26 | public Shock (int num) {
27 | this.bang = num;
28 | baby = starter();
29 | this.bang += num;
30 | }
31 | public static Shock starter() {
32 | Shock gear = new Shock();
33 | return gear;
34 | }
35 | public static void shrink(Shock statik) {
36 | statik.bang -= 1;
37 | }
38 | public static void main(String[] args) {
39 | Shock gear = new Shock(200);
40 | System.out.println(gear.bang); //300
41 | Shock test = new Shock();
42 | System.out.println(gear.bang);
43 | shrink(gear); shrink(starter());
44 | System.out.println(gear.bang); //99
45 | Shock test2 = new Shock();
46 | System.out.println(gear.bang);
47 | System.out.println(gear.bang);
48 | System.out.println(gear.bang);
49 | }
50 | }
51 | ```
52 |
53 | #### 第2题
54 |
55 | 主要是作用域,因为same是实例本身的一个属性,在if判断里又创建了一个same变量,所以当结束作用域后,明白这个same调用的是哪个。
56 |
57 | ```java
58 | public Horse same(Horse horse) {
59 | if (same != null) {
60 | Horse same = horse;
61 | same.same = horse;
62 | same = horse.same;
63 | }
64 | return same.same;
65 | }
66 | ```
67 |
68 | ### 第3题
69 |
70 | 不难,放java visualizier里看看就行。
71 |
72 | 传函数,传的是引用,如果没有对引用里的值更改,那么是不会改变的。
73 |
74 | ```java
75 | public class Foo {
76 | public int x, y;
77 |
78 | public Foo (int x, int y) {
79 | this.x = x;
80 | this.y = y;
81 | }
82 |
83 | public static void switcheroo (Foo a, Foo b) {
84 | Foo temp = a;
85 | a = b;
86 | b = temp;
87 | }
88 |
89 | public static void fliperoo (Foo a, Foo b) {
90 | Foo temp = new Foo(a.x, a.y);
91 | a.x = b.x;
92 | a.y = b.y;
93 | b.x = temp.x;
94 | b.y = temp.y;
95 | }
96 |
97 | public static void swaperoo (Foo a, Foo b) {
98 | Foo temp = a;
99 | a.x = b.x;
100 | a.y = b.y;
101 | b.x = temp.x;
102 | b.y = temp.y;
103 | }
104 |
105 | public static void main (String[] args) {
106 | Foo foobar = new Foo(10, 20);
107 | Foo baz = new Foo(30, 40);
108 | switcheroo(foobar, baz); //foobar.x: 10 foobar.y: 20 baz.x: 30 baz.y: 40
109 | fliperoo(foobar, baz); //foobar.x: 30 foobar.y: 40 baz.x: 10 baz.y: 20
110 | swaperoo(foobar, baz); //foobar.x: 10 foobar.y: 20 baz.x: 10 baz.y: 20
111 | }
112 | }
113 | ```
114 |
115 | ### 第4题
116 |
117 | 放可视化里运行运行:
118 |
119 | ```java
120 | public class QuikMaths {
121 | public static void multiplyBy3(int[] A) {
122 | for (int x: A) {
123 | x = x * 3;
124 | }
125 | }
126 |
127 | public static void multiplyBy2(int[] A) { int[] B = A;
128 | for (int i = 0; i < B.length; i+= 1) {
129 | B[i] *= 2;
130 | }
131 | }
132 |
133 | public static void swap (int A, int B ) {
134 | int temp = B;
135 | B = A;
136 | A = temp;
137 | }
138 |
139 | public static void main(String[] args) {
140 | int[] arr;
141 | arr = new int[]{2, 3, 3, 4};
142 | multiplyBy3(arr);
143 |
144 | /* Value of arr: {2, 3, 3, 4} */
145 |
146 | arr = new int[]{2, 3, 3, 4};
147 | multiplyBy2(arr);
148 |
149 | /* Value of arr: {4, 6, 6, 8} */
150 |
151 | int a = 6;
152 | int b = 7;
153 | swap(a, b);
154 | /* Value of a: 6 Value of b: 7 */
155 | }
156 | }
157 | ```
158 |
159 | ## 2 lab
160 |
161 | lab主要练习debug,我觉得DebugExercise1.java没有bug
162 |
163 | DebugExercise1.java重新写一下很简单的max和sum函数就可以。
164 |
165 | DebugExercise1.java中使用resume(从该断点执行一直到下次这个断点)和条件断点(达到某条件才停止)加快调试过程。
166 |
167 | 解决bug就是找到`-387128732`把负号去掉。
168 |
169 | #### Application: IntLists
170 |
171 | 这里主要是可以在debug的时候使用cs61b老师的插件,超级好用。理解这种`Non-destructive`和`destructive`的设计原理。
172 |
173 | 建议使用递归的方法,而不是迭代的方法,迭代的方法要创建一个新的对象用于迭代,不如递归。
174 |
175 | ### 实现两种函数
176 |
177 | 这里需要考虑nullptr,空指针。怎么办呢。特判吧。
178 |
179 | ## 微信公众号
180 |
181 | 欢迎大家关注我的个人公众号,现阶段主要总结为进入大厂总结的各类知识:Qt,C++,CMake,OpenCV等等
182 | 公众号名称:三丰杂货铺
183 |
184 |
185 |
186 | 
187 |
188 |
--------------------------------------------------------------------------------