Coursera PU 程序设计与算法 Specialization

For quick search
Coursera can be found here

本专项课程旨在系统培养你的程序设计与编写能力。系列课程从计算机的基础知识讲起,无论你来自任何学科和行业背景,都能快速理解;同时我们又系统性地介绍了C程序设计,C++程序设计,算法基础,数据结构与算法相关的内容,各门课之间联系紧密,循序渐进,能够帮你奠定坚实的程序开发基础;课程全部配套在线编程测试,将有效地训练和提升你编写程序的实际动手能力。并通过结业实践项目为你提供应用程序设计解决复杂现实问题的锻炼,从而积累实际开发的经验。因此,我们希望本专项课程能够帮助你完成从仅了解基本的计算机知识到能够利用高质量的程序解决实际问题的转变。

计算导论与C语言基础

Lecture slides can be found [here]
Coursera can be found here

About this course: 你有没有好奇过:计算机为什么能够进行计算?计算机程序是怎样运行的?你是否想知道:计算机未来可能的发展趋势有哪些?程序是如何编写出来的?如何学习程序设计语言?程序设计语言的基本成分有哪些?《计算导论》这门课将帮助你解决这些疑惑。
学完这门课,你将能够解释计算机和程序的基本运行原理以及它们的特性,向你的朋友讲述计算机的历史和发展趋势;同时,你也将充分“热身”,迎接“计算机程序设计语言”的学习!

Week 1 欢迎加入《计算导论与C语言基础》!

欢迎大家来到《计算导论与C语言基础》!在这门课程当中,我们将敲开神秘的计算机世界之门,探索它的历史,解读它的基本原理,讨论它未来的发展趋势;同时我们还将学习C语言这一经典的编程语言,开启我们充满趣味与挑战的程序设计之旅。这个欢迎模块就让我们在出发之前读好“地图”,通过观看两段视频来了解一下这段奇妙的旅程都将涵盖哪些内容吧!PS:我们这门课程一直处在不断地建设与优化当中,吸取了很多以往课程的经典视频,所以如果你看到视频中出现了不同课程的名字,也不要惊讶哦,因为你正在集百家所长。

课程介绍

专项课程介绍2 min

欢迎加入《计算导论与C语言基础》2 min

Week 1 计算机的基本原理

作为开篇的第一次课,我们先来了解一下现代计算机运行的基本原理。我们将从历史上的三次数学危机开始讲起,引出现代计算机的基本原型——图灵机的基本原理,进而解释支撑现代计算机技术的几个基础性理论(二进制、布尔代数、数字逻辑电路)及其解决的基本问题。本次课的主要目的:帮助同学们了解现代计算机的基本原理。本次课的焦点问题:计算机为什么能利用电路实现计算? PS:我们这门课程一直处在不断地建设与优化当中,吸取了很多以往课程的经典视频,所以如果你看到视频中出现了不同课程的名字,也不要惊讶哦,因为你正在集百家所长:)

第一课

从数学危机到图灵机 18 min

图灵机的基本构成 6 min

图灵机的运行机理14 min

http://aturingmachine.com/

第二课

数的二进制表示10 min

二进制数的布尔运算11 min

Week 2 计算机的历史与未来

本次课将带领同学们了解计算机的演变历史,希望通过这个历史演变的过程帮助同学们了解“人类在计算科学方面是如何一步步积累成果的“。在此基础上,我们再来讨论一下未来计算机的发展趋势,并重点介绍了量子计算机的基本原理与研究现状。 本次课的主要目的:希望透过历史引发大家对计算机发展现状的思考。 本次课的焦点问题:未来计算机的发展趋势是什么?为什么不能把CPU造得更大些?什么是量子计算机?

第一课

历史上的计算设备18 min

从电子管到云计算15 min

https://www.top500.org/

第二课

摩尔定律下的计算危机10 min

量子计算机的基本原理8 min

量子计算新成果简介+鼓励9 min

Week 3 程序运行的基本原理

本次课带大家走进计算机,了解计算机的几个基本构成成分及其作用,在此基础上,了解CPU指令的基本执行过程、了解计算机执行程序的过程。 本次课的主要目的:了解计算机是如何运行程序的。 本次课的焦点问题:为什么说现代计算机是冯诺依曼式计算机?电路为什么能存储数字?CPU是不是任意命令都能执行?

第一课

问题的提出4 min

冯诺依曼式计算机8 min

存储器的种类与特点8 min

第二课

存储器的原理与类型10 min

CPU指令的执行8 min

程序的执行9 min

写在下一个部分之前的话

写在下一个部分之前的话10 min

Week 4 感性认识计算机程序

本次课也许是计算机程序设计部分“最重要”的一次课程,在这次课程中,我们将通过一个例子,感受一个结论——“计算机程序 其实是对 人们思维过程的一个描述”;在此基础上,我们将立刻把自己放置于一个“计算机程序设计语言”的设计者的角度,去思考“如果让我们设计一门程序设计语言,我们将如何设计?” 进而,在我们给出关于这个问题的“抽象回答”的基础上,我们迅速地带领大家“快步走进C程序”,迅速了解在C程序设计语言中,都有哪些成分。在这次课的最后,我们通过一个例子,以“感性的方式”让大家感受了一下“什么样的程序是好程序”。 下面就让我们开始这次“最重要”的课程吧——

第一课

说在前面的话5 min

程序是你告诉计算机的话5 min

如果你的大脑是台计算机10 min

如果你来设计一门编程语言10 min

第二课

快步走进C程序之一11 min

快步走进C程序之二9 min

快步走进C程序之三11 min

什么样的程序是好程序3 min

编程作业

Programming Assignment: 感性接触计算机程序3h

编程题#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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//编程题#1:实现冒泡排序
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 请根据自己的理解编写冒泡排序算法,数组大小1000以内
//
// 输入
//
// 第一行是n,表示数组的大小
//
// 接着n行是数组的n个元素
//
// 输出
//
// 排序之后的结果
//
// 一个元素一行
#include<iostream>
using namespace std;
int main() {
int n, a[1000]; //一共n个数,n不超过1000。a用来保存这些数
cin >> n;
// 输入n个数
for (int i = 0; i < n; i++) {
cin >> a[i];
}
// 冒泡,不断比较相邻的两个数,如果顺序错了,那么就交换
for (int i = 0; i < n; i++) {
for (int j = 1; j < n - i; j++) {
if (a[j - 1] > a[j]) {
int temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
}
// 依次输出
for (int i = 0; i < n; i++) {
cout << a[i] << endl;
}
return 0;
}

编程题#2:奇偶排序(一)

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//编程题#2:奇偶排序(一)
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 输入十个整数,将十个整数按升序排列输出,并且奇数在前,偶数在后。
//
// 输入
//
// 输入十个整数
//
// 输出
//
// 按照奇偶排序好的十个整数
#include<iostream>
using namespace std;
int main() {
int a[10];
for (int i = 0; i < 10; i++) {
cin >> a[i];
}
// 首先,我们把奇数放到数组左边,偶数放到数组右边
int l = 0, r = 9; //用左手和右手分别指向数组两端
while (l <= r) {
bool leftIsOdd = a[l] % 2 == 1;
bool rightIsEven = a[r] % 2 == 0;
if (leftIsOdd) {
l++;
} else if (rightIsEven) {
r--;
} else if (!leftIsOdd && !rightIsEven) {
int temp = a[l];
a[l] = a[r];
a[r] = temp;
}
}
// 对l左边(奇数部分)冒泡,不断比较相邻的两个数,如果顺序错了,那么就交换
int start = 0, end = l;
for (int i = start; i < end - 1; i++) {
for (int j = start + 1; j < start + end - i; j++) {
if (a[j - 1] > a[j]) {
int temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
}
// 对l右边(偶数部分)冒泡,不断比较相邻的两个数,如果顺序错了,那么就交换
start = l, end = 10;
for (int i = start; i < end - 1; i++) {
for (int j = start + 1; j < start + end - i; j++) {
if (a[j - 1] > a[j]) {
int temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
}
for (int i = 0; i < 10; i++) {
cout << a[i] << ' ';
}
return 0;
}

编程题#3:奇偶排序(二)

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
37
38
39
40
41
42
43
44
//编程题#3:奇偶排序(二)
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 和上题一样,但是要求用第二种解法
//
// 输入
//
// 输入十个整数
//
// 输出
//
// 按照奇偶排序好的十个整数
#include<iostream>
using namespace std;
int main() {
int a[10];
for (int i = 0; i < 10; i++) {
cin >> a[i];
}
// 冒泡,不断比较相邻的两个数,如果顺序错了,那么就交换
for (int i = 0; i < 9; i++) {
for (int j = 1; j < 10 - i; j++) {
// 与刚才的冒泡排序不同,我们不只是通过较数字的大小决定顺序
// 如果左边的为偶数,右边的为奇数,那么顺序也需要颠倒
bool leftIsEven = a[j - 1] % 2 == 0;
bool rightIsEven = a[j] % 2 == 0;
if ((leftIsEven && !rightIsEven) || (leftIsEven == rightIsEven && a[j - 1] > a[j])) {
int temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
}
for (int i = 0; i < 10; i++) {
cout << a[i] << ' ';
}
return 0;
}

配置编程环境(补充资料)

下载、安装和使用IDE16 min

使用IDE进行调试14 min

Week 5 从现实问题到计算机程序

本次课程堪称计算机程序设计部分“第二重要”的课程。本次课将在大家感受过“什么是计算机程序”的基础上,来回答一个非常基本的问题——“如何设计计算机程序?” 我们将明确阐述“计算机程序是人们对自己头脑中构想的解决方案的描述”这一思想,并通过例子说明“要想写出计算机程序,必须先想出解决方案”的基本道理。 在此基础上,我们还希望通过一个简单的例子,让大家“感性地”了解一下,什么是“结构化的程序设计”(“结构化程序设计”是比“面向对象的程序设计”更基础的设计思想,因此,了解这种思想,非常重要!)。

第一课

没有解决方案就没有程序10 min

先有构想再写程序11 min

第二课

先有构想再写程序-示例12 min

体验结构化的程序-示例23 min

编程作业

Programming Assignment:从现实问题到计算机程序3h

编程题#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
34
35
36
37
38
39
40
41
42
43
44
45
46
//编程题#1: 晶晶赴约会
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 晶晶的朋友贝贝约晶晶下周一起去看展览,但晶晶每周的1、3、5有课必须上课,请帮晶晶判断她能否接受贝贝的邀请,如果能输出YES;如果不能则输出NO。
//
// 输入
//
// 输入有一行,贝贝邀请晶晶去看展览的日期,用数字1到7表示从星期一到星期日。
//
// 输出
//
// 输出有一行,如果晶晶可以接受贝贝的邀请,输出YES,否则,输出NO。注意YES和NO都是大写字母!
//
// 样例输入
//
// 第一组
// 1
// 第二组
// 2
// 第三组
// 3
// 样例输出
//
// 第一组
// NO
// 第二组
// YES
// 第三组
// NO
#include <iostream>
using namespace std;
int main(){
int a;
cin >> a;
if (a == 1 || a == 3 || a == 5)
cout << "NO" << endl;
else
cout << "YES" << endl;
return 0;
}

编程题#2:奇数求和

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//编程题#2:奇数求和
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 计算正整数 m 到 n(包括m 和 n )之间的所有奇数的和,其中,m 不大于 n,且n 不大于300。例如 m = 3, n = 12, 其和则为:3 + 5 + 7 + 9 + 11 = 35
//
// 输入
//
// 两个数 m 和 n,两个数以空格间隔,其中 0 <= m <= n <= 300 。
//
// 输出
//
// 奇数之和
//
// 样例输入
//
// 第一组
// 7 15
// 第二组
// 0 1
// 第三组
// 3 3
// 第四组
// 100 100
// 样例输出
//
// 第一组
// 55
// 第二组
// 1
// 第三组
// 3
// 第四组
// 0
#include <iostream>
using namespace std;
int main(){
int m, n, result = 0;
cin >> m >> n;
while (m <= n){
if (m % 2 == 1)
result += 1;
m++;
}
cout << result << endl;
return 0;
}

编程题#3:整数的个数

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//编程题#3:整数的个数
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 给定k(1<k<100)个正整数,其中每个数都是大于等于1,小于等于10的数。写程序计算给定的k个正整数中,1,5和10出现的次数。
//
// 输入
//
// 输入有两行:第一行包含一个正整数k,第二行包含k个正整数,每两个正整数用一个空格分开。
//
// 输出
//
// 输出有三行,第一行为1出现的次数,,第二行为5出现的次数,第三行为10出现的次数。
//
// 样例输入
//
// 第一组
// 5
// 1 5 8 10 5
// 第二组
// 5
// 2 2 2 2 2
// 样例输出
//
// 第一组
// 1
// 2
// 1
// 第二组
// 0
// 0
// 0
#include <iostream>
using namespace std;
int main(){
int k;
cin >> k;
int n1 = 0, n5 = 0, n10 = 0;
for (int i = 0; i < k; i++){
int n;
cin >> n;
if (n == 1)n1++;
else if (n == 5)n5++;
else if (n == 10)n10++;
}
cout << n1 << endl;
cout << n5 << endl;
cout << n10 << endl;
}

编程题#4: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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//编程题#4:1的个数
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 给定一个十进制整数N,求其对应2进制数中1的个数
//
// 输入
//
// 第一个整数表示有N组测试数据,其后N行是对应的测试数据,每行为一个整数。
//
// 输出
//
// N行,每行输出对应一个输入。
//
// 样例输入
//
// 5
// 2
// 100
// 1000
// 66
// 0
// 样例输出
//
// 1
// 3
// 6
// 2
// 0
// 提示
//
// 这道题有一个特点,那就是输入的数据的个数不止一组了。但是我们知道数组的总数量,所以可以用计数循环来读入数据。
//
// 那么输出应该怎么办呢?在我们的评分系统上,输入和输出是分别放在两个地方处理的,所以可以提早把输出结果打印出来,不会干扰后面的输入。
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
for (int i = 0; i < n; i++){
int x, ans = 0;
cin >> x;
while (x > 0){
ans += x % 2;
x /= 2;
}
cout << ans << endl;
}
return 0;
}

编程题#5:数组逆序重放

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
37
38
39
40
//编程题#5:数组逆序重放
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 将一个数组中的值按逆序重新存放。例如,原来的顺序为8, 6, 5, 4, 1。要求改为1, 4, 5, 6, 8。
//
// 输入
//
// 输入为两行:第一行数组中元素的个数n(1<n<100),第二行是n个整数,每两个整数之间用空格分隔。
//
// 输出
//
// 输出为一行:输出逆序后数组的整数,每两个整数之间用空格分隔。
//
// 样例输入
//
// 5
// 8 6 5 4 1
// 样例输出
//
// 1 4 5 6 8
// 参考答案
#include <iostream>
using namespace std;
int a[100];
int main(){
int n;
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i];
while (n--){
cout << a[n];
if (n>0)cout << " ";
}
return 0;
}

写在下一个部分之前的话

写在下一个部分之前的话10 min

Week 6 理性认识C程序 导论

本次课帮助大家了解C语言的历史,了解C语言规范(Specification)的版本演进,了解C语言的规范是一个“宽松”的规范;在此基础上,我们将阐述一门程序设计语言所包含的四种基本成分(如上所述)。 焦点问题:为什么相同的C程序在不同的C程序编译器上,会编译出不同的结果?

第一课

明确学习进度2 min

C语言的由来12 min

C语言的标准9 min

C语言的构成4 min

编程作业

Programming Assignment: 理性认识C程序 导论 抄写题3h

抄写题#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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//抄写题#1:细菌实验分组
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 有一种细菌分为A、B两个亚种,它们的外在特征几乎完全相同,仅仅在繁殖能力上有显著差别,A亚种繁殖能力非常强,B亚种的繁殖能力很弱。在一次为时一个小时的细菌繁殖实验中,实验员由于疏忽把细菌培养皿搞乱了,请你编写一个程序,根据实验结果,把两个亚种的培养皿重新分成两组。
//
// 细菌繁殖能力(繁殖率)的量化标准为一个小时内细菌数量增长的比例(繁殖率 = 一小时后细菌数量 / 原本细菌数量)。
//
// 两个亚种繁殖能力差异很大,这意味着对于任意两个同种细菌培养皿的繁殖率的测量值之间的差异要小于任意两个异种细菌培养皿繁殖率的测量值之间的差异。即:
//
//
// 输入
//
// 输入有多行,第一行为整数n(n≤100),表示有n个培养皿。
//
// 其余n行,每行有三个整数,分别代表培养皿编号,试验前细菌数量,试验后细菌数量。假设试验没有误差。
//
// 输出
//
// 输出有多行:
//
// 第一行输出A亚种培养皿的数量,其后每行输出A亚种培养皿的编号,按繁殖率升序排列。
//
// 然后一行输出B亚种培养皿的数量,其后每行输出B亚种培养皿的编号,也按繁殖率升序排列。
//
// 样例输入
//
// 5
// 1 10 3456
// 2 10 5644
// 3 10 4566
// 4 20 234
// 5 20 232
// 样例输出
//
// 3
// 1
// 3
// 2
// 2
// 5
// 4
// 提示
//
// 亚种内部,细菌繁殖能力差异远远小于亚种之间细菌繁殖能力的差异。
//
// 也就是说,亚种间任何两组细菌的繁殖率之差都比亚种内部两组细菌的繁殖率之差大。
//
// 请完全按照如下的程序书写代码,并在书写的过程中体会优秀的代码风格:
#include <iostream>
using namespace std;
int main(){
int n;
int id[100];
double rate[100];
cin >> n;
for (int i = 0; i < n; i++){
int initial, final;
cin >> id[i] >> initial >> final;
rate[i] = (double)final / initial;
}
for (int i = 0; i < n; i++){
for (int j = 0; j < n - i - 1; j++){
if (rate[j + 1]>rate[j]){
int temId = id[j];
id[j] = id[j + 1];
id[j + 1] = temId;
double temRate = rate[j];
rate[j] = rate[j + 1];
rate[j + 1] = temRate;
}
}
}
double maxDiff = 0;
int maxDiffIndex = 0;
for (int i = 0; i < n - 1; i++){
double diff = rate[i] - rate[i + 1];
if (maxDiff < diff){
maxDiff = diff;
maxDiffIndex = i;
}
}
cout << maxDiffIndex + 1 << endl;
for (int i = maxDiffIndex; i >= 0; i--){
cout << id[i] << endl;
}
cout << n - maxDiffIndex - 1 << endl;
for (int i = n - 1; i >= maxDiffIndex + 1; i--){
cout << id[i] << endl;
}
return 0;
}

Programming Assignment: 理性认识C程序 导论 编程题3h

编程题#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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//编程题#1:苹果和虫子
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 你买了一箱n个苹果,很不幸的是买完时箱子里混进了一条虫子。虫子每x小时能吃掉一个苹果,假设虫子在吃完一个苹果之前不会吃另一个,那么经过y小时你还有多少个完整的苹果?
//
// 输入
//
// 输入仅一行,包括n,x和y(均为整数)。
//
// 输出
//
// 输出也仅一行,剩下的苹果个数
//
// 样例输入
//
// 第一组
// 10 4 9
// 第二组
// 10 4 36
// 第三组
// 10 4 100
// 样例输出
//
// 第一组
// 7
// 第二组
// 1
// 第三组
// 0
// 提示
//
// 注意:是要求完整的苹果数。
#include <iostream>
using namespace std;
int main(){
int n, x, y;
cin >> n >> x >> y;
int mod = 0;
if (y%x != 0) mod += 1;
int result;
result = n - (y / x) - mod;
if (result < 0)
cout << 0 << endl;
else
cout << n - (y / x) - mod << endl;
return 0;
}

编程题#2:大象喝水

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//编程题#2:大象喝水
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 一只大象口渴了,要喝20升水才能解渴,但现在只有一个深h厘米,底面半径为r厘米的小圆桶(h和r都是整数)。问大象至少要喝多少桶水才会解渴。
//
// 输入
//
// 输入有一行:包行两个整数,以一个空格分开,分别表示小圆桶的深h和底面半径r,单位都是厘米。
//
// 输出
//
// 输出一行,包含一个整数,表示大象至少要喝水的桶数。
//
// 样例输入
//
// 第一组
// 23 11
// 第二组
// 1 1
// 样例输出
//
// 第一组
// 3
// 第二组
// 6367
// 提示
//
// 如果一个圆桶的深为h厘米,底面半径为r厘米,那么它最多能装Pi * r * r * h立方厘米的水。(设Pi = 3.14159)
//
// 1升 = 1000毫升
//
// 1毫升 = 1 立方厘米
//
// 来源
//
// 计算概论化学学院期末考试
#include <iostream>
using namespace std;
int main(){
double Pi = 3.14159;
int total = 20000;
int h, r;
cin >> h >> r;
double V;
V = Pi * r * r * h;
double result;
result = total / V;
if (result == (int)result)
cout << result << endl;
else
cout << (int)result + 1 << endl;
}

编程题#3:最高的分数

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
37
38
39
40
41
42
43
44
//编程题#3:最高的分数
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 孙老师讲授的《计算概论》这门课期中考试刚刚结束,他想知道考试中取得的最高分数。因为人数比较多,他觉得这件事情交给计算机来做比较方便。你能帮孙老师解决这个问题吗?
//
// 输入
//
// 输入两行,第一行为整数n(1 <= n < 100),表示参加这次考试的人数.第二行是这n个学生的成绩,相邻两个数之间用单个空格隔开。所有成绩均为0到100之间的整数。
//
// 输出
//
// 输出一个整数,即最高的成绩。
//
// 样例输入
//
// 5
// 85 78 90 99 60
// 样例输出
//
// 99
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
int score[100];
for (int i = 0; i < n; i++){
cin >> score[i];
}
int maxScore = 0;
for (int i = 0; i < n; i++){
if (score[i]>maxScore)
maxScore = score[i];
}
cout << maxScore << endl;
return 0;
}

编程题#4:最大奇数与最小偶数之差的绝对值

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//编程题#4:最大奇数与最小偶数之差的绝对值
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 输入6个正整数,且这6个正整数中至少存在一个奇数和一个偶数。
//
// 设这6个正整数中最大的奇数为a,最小的偶数为b,求出 | a - b | 的值
//
// 输入
//
// 输入为一行,6个正整数, 且6个正整数都小于100
//
// 输入保证这6个数中至少存在一个奇数和一个偶数
//
// 输出
//
// 输出为一行,输出最大的奇数与最小的偶数之差的绝对值
//
// 样例输入
//
// 第一组
// 1 2 3 4 5 6
// 第二组
// 1 6 3 8 5 10
//
// 样例输出
//
// 第一组
// 3
// 第二组
// 1
#include <iostream>
using namespace std;
int main(){
int a[6];
for (int i = 0; i < 6; i++){
cin >> a[i];
}
int MaxEven = 1;
int MinOdd = 100;
for (int i = 0; i < 6; i++){
if (a[i] % 2 == 0){
if (a[i] < MinOdd){
MinOdd = a[i];
}
}
else{
if (a[i]>MaxEven){
MaxEven = a[i];
}
}
}
cout << abs(MaxEven - MinOdd) << endl;
return 0;
}

编程题#5:分离整数的各个数位

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
//编程题#5:分离整数的各个数位
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 从键盘输入一个任意的三位整数,要求正确地分离出它的百位、十位和个位数,并分别在屏幕上输出,输出采用每行输出一个数的方式,不带其它符号。
//
// 输入
//
// 一个任意的三位整数
//
// 输出
//
// 一个任意的三位整数
//
// 样例输入
//
// 123
// 样例输出
//
// 1
// 2
// 3
#include <iostream>
using namespace std;
int main(){
int a;
cin >> a;
cout << a / 100 << endl;
cout << a % 100 / 10 << endl;
cout << a % 100 % 10 << endl;
}

Week 7 C语言中的数据成分

本节我们将介绍C语言中的“数据成分”。重点在于:掌握各种数据类型在内存中所占的空间大小,掌握各种数据类型的特点。

第一课

再谈学习进度与安排5 min

变量定义的含义10 min

整数型的类别11 min

第二课

整数型的存储9 min

整数的输入输出7 min

最大与最小整数10 min

第三课

浮点型11 min

字符型8 min

布尔型3 min

常数6 min

变量命名8 min

编程作业

Programming Assignment: 数据成分应用练习3h

抄写题#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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//抄写题#1: 约瑟夫问题
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。
//
// 输入
//
// 每行是用空格分开的两个整数,第一个是 n, 第二个是 m(0 < m, n <= 300)。最后一行是:
//
// 0 0
//
// 输出
//
// 对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号
//
// 样例输入
// 6 2
// 12 4
// 8 3
// 0 0
// 样例输出
//
//5
//1
//7
#include <iostream>
using namespace std;
//一共最多有300只猴子
int succedent[300]; //这个数组用于保存一个猴子后一位是谁,
//比如“next[5]的值是7”就是说5号猴子的下一位是7号猴子,6号猴子已经在之前退出了。
int precedent[300];//这个数组用于保存一个猴子前一位是谁,用法和上面的类似。
int main(){
int n, m;
while (true){
cin >> n >> m;
if (n == 0 && m == 0)
break;
for (int i = 0; i < n - 1; i++){
succedent[i] = i + 1;
precedent[i + 1] = i;
}
succedent[n - 1] = 0;
precedent[0] = n - 1;
int current = 0;
while (true){
// 如果一共要报m次号,那么取m - 1次succedent之后就是需要退出的那只猴子
for (int count = 0; count < m - 1; count++)
current = succedent[current];
int pre = precedent[current];
int suc = succedent[current];
//让current号猴子退出很简单,就是把前一位的“下一位”指向current的下一位,
//下一位的“前一位”指向current的前一位就好了
succedent[pre] = suc;
precedent[suc] = pre;
if (pre == suc){
//如果只剩下两个了,那么每个人的前位和后位就是同一个了。
//current是退出的,那么另一个就是剩下的。
//我们的序号是从0编号的,输出时要加一
cout << pre + 1 << endl;
break;
}
current = suc;
}
}
return 0;
}

抄写题#2:分数求和

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//抄写题#2:分数求和
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 输入n个分数并对他们求和,用约分之后的最简形式表示。
//
// 比如:
//
// q / p = x1 / y1 + x2 / y2 + .... + xn / yn,
//
// q / p要求是归约之后的形式。
//
// 如:5 / 6已经是最简形式,3 / 6需要规约为1 / 2, 3 / 1需要规约成3,10 / 3就是最简形式。
//
// PS : 分子和分母都没有为0的情况,也没有出现负数的情况
//
// 输入
//
// 第一行的输入n, 代表一共有几个分数需要求和
//
// 接下来的n行是分数
//
// 输出
//
// 输出只有一行,即归约后的结果
//
// 样例输入
//
// 2
// 1 / 2
// 1 / 3
// 样例输出
//
// 5 / 6
// 请完全按照如下的程序书写代码,并在书写的过程中体会优秀的代码风格:
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
int sumn = 0, sumd = 1;//储存结果,sumn/sumd
while (n--){
int num, deno;
char slash;//专门用来吃掉/的
cin >> num >> slash >> deno;
//先相加 a/b + c/d = (a*d+c*b)/(b*d)
sumn = sumn*deno + num*sumd;
sumd = sumd*deno;
}
//后约分
//先求最大公约数gcd,这里用的是欧几里得法
int a = sumd, b = sumn, c;
while (a != 0){
c = a; a = b%a; b = c;
}
int gcd = b;
//分子分母同时除以gcd就可以完成约分
sumd /= gcd;
sumn /= gcd;
if (sumd > 1)
cout << sumn << '/' << sumd << endl;
else
cout << sumn << endl;
return 0;
}
//我们计算过程中结果分母是不断乘以新输入的分母,最后约分的。这样可能导致这个过程中分母过大溢出。
//这道题的数据比较简单,并没有出现那种情况。但大家可以思考一下,如果出现了那种情况怎么办呢?(不要用大整数啊)
/*我给大家一组测试数据,看看你修改过的程序能不能通过这组数据吧:
样例输入:
2
1/100000000
1/100000000
样例输出:
1/50000000
*/

Programming Assignment: 综合练习(1)3h

编程题#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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//编程题#1:年龄与疾病
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 某医院想统计一下某项疾病的获得与否与年龄是否有关,需要对以前的诊断记录进行整理。
//
// 输入
//
// 共2行,第一行为过往病人的数目n(0 < n <= 100),第二行为每个病人患病时的年龄。
//
// 输出
//
// 每个年龄段(分四段:18以下,19 - 35,36 - 60,大于60注意看样例输出的格式)的患病人数占总患病人数的比例,以百分比的形式输出,精确到小数点后两位(double)。关于c++的格式化的输入输出,请参考:http://www.cplusplus.com/reference/iomanip。也可以在网上搜索一下,资料很多的。
//
//样例输入
//
//
//
//10
//1 11 21 31 41 51 61 71 81 91
//样例输出
//
//
//
//1 - 18: 20.00 %
//19 - 35 : 20.00 %
//36 - 60 : 20.00 %
//60 - : 40.00%
//提示
//
//注意最后一行的输出是“60 - : ”,而不是“61 - : ”。
//
//每个冒号之后有一个空格。
//
//输出可以用 cout << fixed << setprecision(2) << f; 来保留f后面的两位小数。
#include<iostream>
#include<iomanip>
using namespace std;
int main(){
int n;
cin >> n;
float f_18, f_35, f_60, f_100;
f_18 = f_35 = f_60 = f_100 = 0;
for (int i = 0; i < n; i++){
int tem;
cin >> tem;
if (tem <= 18)
f_18 += 1;
else if (tem <= 35)
f_35 += 1;
else if (tem <= 60)
f_60 += 1;
else
f_100 += 1;
}
f_18 = f_18 / n * 100;
f_35 = f_35 / n * 100;
f_60 = f_60 / n * 100;
f_100 = f_100 / n * 100;
cout << "1-18: "<<fixed << setprecision(2) << f_18 <<'%'<< endl;
cout << "19-35: " << fixed << setprecision(2) << f_35 << '%' << endl;
cout << "36-60: "<<fixed << setprecision(2) << f_60 << '%' << endl;
cout << "60-: "<<fixed << setprecision(2) << f_100 << '%' << endl;
return 0;
}

编程题#2:成绩判断

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//编程题#2:成绩判断
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 6000kB
//
// 描述
//
// 输入一个0--100的分数,判断分数代表什么等级。
//
// 95 <= 分数 <= 100, 输出1
//
// 90 <= 分数<95, 输出2
//
// 85 <= 分数<90, 输出3
//
// 80 <= 分数<85, 输出4
//
// 70 <= 分数<80, 输出5
//
// 60 <= 分数<70输出6
//
// 分数 < 60; 输出7.
//
// 输入
//
// n
//
// 输出
//
// m
//
// 样例输入
//
//
// 
// 87
// 样例输出
//
//
// 
// 3
#include<iostream>
using namespace std;
int main(){
int n, m;
cin >> n;
if (n < 60)
m = 7;
else if (n < 70)
m = 6;
else if (n < 80)
m = 5;
else if (n < 85)
m = 4;
else if (n < 90)
m = 3;
else if (n < 95)
m = 2;
else if (n <= 100)
m = 1;
cout << m << endl;
return 0;
}

编程题#3:找出第k大的数

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//编程题#3:找出第k大的数
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 用户输入N和K,然后接着输入N个正整数(无序的),程序在不对N个整数排序的情况下,找出第K大的数。注意,第K大的数意味着从大到小排在第K位的数。
//
// 输入
//
// N
//
// K
//
// a1 a2 a3 a4 .....aN
//
// 输出
//
// b
//
// 样例输入
//
//
// 
// 5
// 2
// 32 3 12 5 89
// 样例输出
//
//
// 
// 32
// 提示
//
// 这是一道很经典的算法问题,是公司面试的常见考题。以后学习递归之后再回头看看这道题,或许有新解法。
//
#include<iostream>
using namespace std;
int main(){
int N, K,b;
b = 0;
cin >> N >> K;
int a[1000];
for (int i = 0; i < N; i++){
cin >> a[i];
}
for (int i = N; i < 1000; i++){
a[i]=0;
}
for (int i = 0; i < N; i++){
int n_greater = 0;
int n_equal = 0;
for (int j = 0; j < N; j++){
if (a[i]<a[j])
n_greater += 1;
else if (a[i] == a[j])
n_equal += 1;
}
if ((n_greater + n_equal)>=K){
if (n_greater>=K){
continue;
}
else{
b = a[i];
break;
}
}
//if (n_equal >= (K - n_greater))
// b = a[i];
//break;
}
cout << b << endl;
return 0;
}

编程题#4:人民币支付

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//编程题#4:人民币支付
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 从键盘输入一指定金额(以元为单位,如345),然后输出支付该金额的各种面额的人民币数量,显示100元,50元,20元,10元,5元,1元各多少张,要求尽量使用大面额的钞票。
//
// 输入
//
// 一个小于1000的正整数。
//
// 输出
//
// 输出分行,每行显示一个整数,从上到下分别表示100元,50元,20元,10元,5元,1元人民币的张数
//
// 样例输入
//
//
// 
// 735
// 样例输出
//
//
// 
// 7
// 0
// 1
// 1
// 1
// 0
#include<iostream>
using namespace std;
int main(){
int n;
cin >> n;
int N_100, N_50, N_20, N_10, N_5, N_1;
N_100= N_50= N_20= N_10= N_5= N_1=0;
N_100 = n / 100;
n = n % 100;
N_50 = n / 50;
n = n % 50;
N_20 = n / 20;
n = n % 20;
N_10 = n / 10;
n = n % 10;
N_5 = n / 5;
n = n % 5;
N_1 = n / 1;
cout << N_100 << '\n' << N_50 << '\n' << N_20 << '\n'
<< N_10 << '\n' << N_5 << '\n' << N_1 << endl;
return 0;
}

Week 8 C语言中的运算成分

本节我们将介绍C语言中的“运算成分”。重点在于:掌握各种运算符的基本含义,特别需要掌握“由各种运算符引起的数据类型转换规律”。

第一课

说在前面的话3 min

赋值运算18 min

赋值运算的说明10 min

第二课

算术运算15 min

自增自减运算22 min

第三课

关系运算6 min

逻辑运算与混合运算19 min

第四课

逗号,条件,强转11 min

位运算17 min

编程作业

Programming Assignment: 逻辑运算应用程序抄写练习3h

抄写题#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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//抄写题#1:点评赛车
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 4名专家对4款赛车进行评论
//
// 1)A说:2号赛车是最好的;
//
// 2)B说:4号赛车是最好的;
//
// 3)C说:3号赛车不是最好的;
//
// 4)D说: B说错了。
//
// 事实上只有1款赛车最佳,且只有1名专家说对了,其他3人都说错了。
//
// 请编程输出最佳车的车号,以及说对的专家。
//
// 输入
//
// 无输入。
//
// 输出
//
// 输出两行。第一行输出最佳车的车号(1 - 4中的某个数字)。第二行输出说对的专家(A - D中的某个字母)。
//
// 样例输入
//
// (无)
// 样例输出
//
// 1
// A
// 提示
//
// 样例输出只是格式说明,并非正确答案
//
// 通过这道题我们想让大家知道如何通过枚举处理逻辑判断问题。
#include<iostream>
using namespace std;
int main(){
// 很多同学在论坛中问,autograder是怎么工作的。
// 答案就是:autograder只看在所有测试用例上的输出是否正确。
// 由于本题没有输入,输出也唯一,
// 所以,如果我们知道了答案(例如人工地一一枚举过来)那我们就可以直接输出啦!结果如下:
// cout << "3" << endl << "D" << endl;
// oj系统的autograder可辨识不了我们的程序使用的算法是否符合要求
//(事实上,任何关于程序的非平凡性质都是不可判定的!
// ————等等,那autograder怎么工作呢?
// ————原来,autograder限制了程序运行的时间。其目的当然包括要求我们使用的算法不能太笨拙。
// 更重要的是,如果我们允许最笨拙的方法并且对时间不作任何限制,
// 那么autograder就不能正确判定所有的程序啦。)
// 不过呢,这么输出是对autograder的一种错误使用方式,因为显然这不是本道题的考察内容。
// 所以,我们还是老老实实地用“程序”来解这个问题的答案。
// 用best枚举最好的车
int best;
for (best = 1; best <= 4; best++){
// a b c d记录四位专家的话
bool a = (best == 2);
bool b = (best == 4);
bool c = !(best == 3);
bool d = !b;
if (a + b + c + d != 1)
continue; // 不符合只有1位专家说对的条件
// 输出最佳的车
cout << best << endl;
// 输出判断正确的专家
if (a == 1)
cout << "A" << endl;
else if (b == 1)
cout << "B" << endl;
else if (c == 1)
cout << "C" << endl;
else
cout << "D" << endl;
}
return 0;
}

Programming Assignment: 综合练习(2)3h

编程题#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
34
35
36
37
38
39
40
41
42
//编程题#1:数字求和
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 给定一个正整数a,以及另外的5个正整数,问题是:这5个整数中,小于a的整数的和是多少?
//
// 输入
//
// 输入一行,只包括6个小于100的正整数,其中第一个正整数就是a。
//
// 输出
//
// 输出一行,给出一个正整数,是5个数中小于a的数的和。
//
// 样例输入
//
// 10 1 2 3 4 11
//
// 样例输出
//
// 10
#include<iostream>
using namespace std;
int main(){
int lst[6];
for (int i = 0; i < 6; i++){
cin >> lst[i];
}
int a = lst[0];
int s = 0;
for (int i = 1; i < 6; i++){
if (lst[i] < a)
s += lst[i];
}
cout << s << endl;
return 0;
}

编程题#2:骑车与走路

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//编程题#2:骑车与走路
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 在北大校园里, 没有自行车, 上课办事会很不方便.但实际上, 并非去办任何事情都是骑车快, 因为骑车总要找车、开锁、停车、锁车等, 这要耽误一些时间.假设找到自行车, 开锁并车上自行车的时间为27秒; 停车锁车的时间为23秒; 步行每秒行走1.2米, 骑车每秒行走3.0米.请判断走不同的距离去办事, 是骑车快还是走路快.
//
// 输入
//
// 第一行为待处理的数据的数量n
//
// 其后每一行整数为一次办事要行走的距离, 单位为米.
//
// 输出
//
// 对应每个整数, 如果骑车快, 输出一行"Bike"; 如果走路快, 输出一行"Walk"; 如果一样快, 输出一行"All".
//
// 样例输入
//
// 4
// 50
// 90
// 120
// 180
// 样例输出
//
//
// Walk
// Walk
// Bike
// Bike
// 提示
//
// 注意数据类型,应当使用浮点数来保存结果
#include<iostream>
using namespace std;
int main(){
int n;
cin >> n;
int distance;
for (int i = 0; i < n; i++){
cin >> distance;
float BikeTime, WalkTime;
WalkTime = distance / 1.2;
BikeTime = distance / 3.0 + 50;
if (WalkTime>BikeTime)
cout << "Bike" << endl;
else if (WalkTime==BikeTime)
cout << "All" << endl;
else
cout << "Walk" << endl;
}
return 0;
}

编程题#3:买房子

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//编程题#3:买房子
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 某程序员开始工作,年薪N万,他希望在中关村公馆买一套60平米的房子,现在价格是200万,假设房子价格以每年百分之K增长,并且该程序员未来年薪不变,且不吃不喝,不用交税,每年所得N万全都积攒起来,问第几年能够买下这套房子(第一年房价200万,收入N万)。程序员每年先拿工资,再尝试买房,然后房子才涨价。
//
// 输入
//
// 有多行,每行两个整数N(10 <= N <= 50), K(1 <= K <= 20)
//
// 输出
//
// 针对每组数据,如果在第20年或者之前就能买下这套房子,则输出一个整数M,表示最早需要在第M年能买下,否则输出Impossible,输出需要换行
//
// 样例输入
//
//
// 50 10
// 40 10
// 40 8
// 样例输出
//
//
// 
// 8
// Impossible
// 10
// 提示
//
// 注意数据类型,应当使用浮点数来保存结果
//
// C++里多行输入(在不知道一共有多少行的情况下)可以使用下面的语句,每输入一组数据就可以输出其结果,不用等待所有数据都输入完毕。
//
//
//while (cin >> N >> K){
// //do your magic
//}
#include<iostream>
using namespace std;
int main(){
int N, K;
float s, money;
while (cin >> N >> K){
//do your magic
money = N;
s = 200;
for (int i = 1; i <= 100; i++){
if (money >= s){
cout << i << endl;
break;
}
else{
money += N;
s += s*K*0.01;
if (i == 100){
cout << "Impossible" << endl;
break;
}
}
}
}
return 0;
}

编程题#4:找和为K的两个元素

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//编程题#4:找和为K的两个元素
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 在一个长度为n(n < 1000)的整数序列中,判断是否存在某两个元素之和为k。
//
// 输入
//
// 第一行输入序列的长度n和k,用空格分开。
//
// 第二行输入序列中的n个整数,用空格分开。
//
// 输出
//
// 如果存在某两个元素的和为k,则输出yes,否则输出no。
//
// 样例输入
//
// 9 10
// 1 2 3 4 5 6 7 8 9
// 样例输出
//
// yes
//
#include<iostream>
using namespace std;
int main(){
int n, k,a[1000];
cin >> n >> k;
for (int i = 0; i < n; i++){
cin >> a[i];
}
for (int i = n; i < 1000; i++){
a[i]=0;
}
for (int i = 0; i < n-1; i++){
for (int j = i+1; j < n; j++){
if (a[i] + a[j] == k){
cout << "yes" << endl;
return 0;
}
}
}
cout << "no" << endl;
return 0;
}

编程题#5:自整除数

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//编程题#5:自整除数
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 对一个整数n, 如果其各个位数的数字相加得到的数m能整除n, 则称n为自整除数.例如21, 21 % (2 + 1) == 0, 所以21是自整除数.现求出从10到n(n < 100)之间的所有自整除数.
//
// 输入
//
// 有一行, 整数n, (10 <= n < 100)
//
// 输出
//
// 有多行.按从小到大的顺序输出所有大于等于10, 小于等于n的自整除数, 每行一个自整除数.
//
// 样例输入
//
// 47
// 样例输出
//
// 10
// 12
// 18
// 20
// 21
// 24
// 27
// 30
// 36
// 40
// 42
// 45
// 来源
//
// 计算概论05
#include<iostream>
using namespace std;
int main(){
int n;
cin >> n;
int s = 0;
for (int i = 10; i < n; i++){
s = i / 10+ i % 10;
if (i%s == 0)
cout << i << endl;
}
return 0;
}

Week 9 C语言中的控制成分

本节我们将介绍C语言中的“控制成分”。重点在于:掌握各种控制语句的使用方式。顺便,了解一下历史上的Goto之争。

第一课

再谈分支语句22 min

第二课

再谈循环语句18 min

Goto之争13 min

Week 10 C程序中的数组

在学习了C程序语言的几种重要的构成成分之后,为了帮助大家能够更好地使用已经学到的C语言成分编写程序,我们再介绍一种非常重要的数据结构——数组。 本部分的重点在于:掌握数组的定义、引用方法,并掌握数组的基本作用。特别的,需要大家掌握利用数组的下标来解决问题的“技巧”。

第一课

再谈一维数组9 min

二维数组12 min

三维数组5 min

第二课

数组的作用之一9 min

数组的作用之二 17 min

编程作业

Programming Assignment: 数组应用练习3h

编程题#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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//编程题#1:求字母的个数
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 在一个字符串中找出元音字母a, e, i, o, u出现的次数。
//
// 输入
//
// 输入一行字符串(字符串中可能有空格,请用cin.getline(s, counts)方法把一行字符串输入到字符数组s中,其中counts是s的最大长度,这道题里面可以直接写80。),字符串长度小于80个字符。
//
// 输出
//
// 输出一行,依次输出a, e, i, o, u在输入字符串中出现的次数,整数之间用空格分隔。
//
// 样例输入
//
// If so, you already have a Google Account.You can sign in on the right.
// 样例输出
//
// 5 4 3 7 3
// 提示
//
// 注意,只统计小写元音字母a, e, i, o, u出现的次数。
#include<iostream>
using namespace std;
int main(){
char s[80];
cin.getline(s, 80);
int len;
int a[6] = { 0 };
for (len = 0; s[len] != '\0'; len++){
switch (s[len])
{
case 'a': a[1]++; break;
case 'e': a[2]++; break;
case 'i': a[3]++; break;
case 'o': a[4]++; break;
case 'u': a[5]++; break;
default:
break;
}
}
for (int i = 1; i < 6; i++)
cout << a[i] << ' ';
return 0;
}

编程题#2:忽略大小写比较字符串大小

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//编程题#2:忽略大小写比较字符串大小
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 一般我们用strcmp可比较两个字符串的大小,比较方法为对两个字符串从前往后逐个字符相比较(按ASCII码值大小比较),直到出现不同的字符或遇到'\0'为止。如果全部字符都相同,则认为相同;如果出现不相同的字符,则以第一个不相同的字符的比较结果为准。但在有些时候,我们比较字符串的大小时,希望忽略字母的大小,例如"Hello"和"hello"在忽略字母大小写时是相等的。请写一个程序,实现对两个字符串进行忽略字母大小写的大小比较。
//
// 输入
//
// 输入为两行,每行一个字符串,共两个字符串。(请用cin.getline(s, 80)录入每行字符串)(每个字符串长度都小于80)
//
// 输出
//
// 如果第一个字符串比第二个字符串小,输出一个字符"<"
//
// 如果第一个字符串比第二个字符串大,输出一个字符">"
//
// 如果两个字符串相等,输出一个字符"="
//
// 样例输入
//
// 第一组
// Hello
// hello
// 第二组
// hello
// HI
// 第三组
// hello
// HELL
// 样例输出
//
// 第一组
// =
// 第二组
// <
// 第三组
// >
// 提示
//
// strcmp的实现如下,结果用result保存。
//
// int i = 0;
// char result;
// while (s1[i] != '\0' && (s1[i] == s2[i])){
// i++;
// }
// if (s1[i] > s2[i]) {
// result = '>';
// }
// else if (s1[i] < s2[i]) {
// result = '<';
// }
// else{
// result = '=';
// }
// (((s1[i] >= 65) && (s1[i] <= 90)) ? (s1[i] + 32) : s1[i])
#include<iostream>
using namespace std;
int main(){
char s1[80], s2[80];
cin.getline(s1, 80); cin.getline(s2, 80);
int i = 0;
char result;
char s1_tem = (((s1[0] >= 65) && (s1[0] <= 90)) ? (s1[0] + 32) : s1[0]);
char s2_tem = (((s2[0] >= 65) && (s2[0] <= 90)) ? (s2[0] + 32) : s2[0]);
while (s1[i] != '\0' && (s1_tem == s2_tem)){
i++;
s1_tem = (((s1[i] >= 65) && (s1[i] <= 90)) ? (s1[i] + 32) : s1[i]);
s2_tem = (((s2[i] >= 65) && (s2[i] <= 90)) ? (s2[i] + 32) : s2[i]);
}
if (s1_tem > s2_tem) {
result = '>';
}
else if (s1_tem < s2_tem) {
result = '<';
}
else{
result = '=';
}
cout << result << endl;
return 0;
}

编程题#3:最长单词2

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//编程题#3:最长单词2
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 一个以'.'结尾的简单英文句子,单词之间用空格分隔,没有缩写形式和其它特殊形式
//
// 输入
//
// 一个以'.'结尾的简单英文句子(长度不超过500),单词之间用空格分隔,没有缩写形式和其它特殊形式
//
// 输出
//
// 该句子中最长的单词。如果多于一个,则输出第一个
//
// 样例输入
//
// 第一组
// I am a student of Peking University.
// 第二组
// Hello world.
// 样例输出
//
// 第一组
// University
// 第二组
// Hello
#include<iostream>
using namespace std;
int main(){
char s[500];
cin.getline(s, 500, '.');
int Flag = 0;
int StartP = 0;
int EndP = 0;
int MaxNum = 0;
int position[2] = { 0 };
for (int i = 0; s[i] != '\0'; i++){
if (s[i] == ' '){
//end of the word
if (Flag == 1){
int tem = EndP -StartP+1;
if (tem > MaxNum){
MaxNum = tem;
position[0] = StartP;
position[1] = EndP;
}
}
Flag = 0;
}
//s[i]!=' ' && Flag==0
//start of new word!
else if (Flag == 0){
Flag = 1;
StartP = i;
EndP = i;
}
//s[i]!=' ' && Flag==1
else{
EndP = i;
}
}
int tem = EndP - StartP + 1;
if (tem > MaxNum){
MaxNum = tem;
position[0] = StartP;
position[1] = EndP;
}
for (int i = position[0]; i <= position[1]; i++){
cout << s[i];
}
return 0;
}

编程题#4:矩阵交换行

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//编程题#4:矩阵交换行
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 在main函数中, 生成一个5 * 5的矩阵,输入矩阵数据,并输入n,m的值。判断n,m是否在数组范围内,如果不在,则输出error;如果在范围内,则将n行和m行交换,输出交换n,m后的新矩阵。
//
// 输入
//
// 5 * 5矩阵的数据,以及n和m的值。
//
// 输出
//
// 如果不可交换,则输出error
//
// 如果可交换,则输出新矩阵
//
// 样例输入
//
// 第一组
// 1 2 2 1 2
// 5 6 7 8 3
// 9 3 0 5 3
// 7 2 1 4 6
// 3 0 8 2 4
// 0 4
// 第二组
// 1 2 2 1 2
// 5 6 7 8 3
// 9 3 0 5 3
// 7 2 1 4 6
// 3 0 8 2 4
// 5 1
// 样例输出
//
// 第一组
// 3 0 8 2 4
// 5 6 7 8 3
// 9 3 0 5 3
// 7 2 1 4 6
// 1 2 2 1 2
// 第二组
// error
// 提示
//
// 输出error格式如下:
//
// cout << "error" << endl;
//
//输出矩阵格式如下:
//
//cout << setw(4) << num;
//
//输出矩阵一行后要输出cout << endl;
//
//setw是iomanip库里定义的格式控制操作符,需要#include <iomanip> 包含这个头文件。
//
#include<iostream>
#include<iomanip>
using namespace std;
int main(){
int a[5][5] = { 0 };
int n, m;
for (int i = 0; i < 5; i++)
for (int j = 0; j < 5; j++)
cin >> a[i][j];
cin >> n >> m;
if ((n >= 0 && n <= 4) && (m >= 0 && m <= 4)){
int tem[5];
for (int j = 0; j < 5; j++){
tem[j] = a[n][j];
a[n][j] = a[m][j];
a[m][j] = tem[j];
}
for (int i = 0; i < 5; i++){
for (int j = 0; j < 5; j++){
cout << setw(4) << a[i][j];
}
cout << endl;
}
}
else
cout << "error" << endl;
return 0;
}

编程题#5:异常细胞检测

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//编程题#5:异常细胞检测
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 我们拍摄的一张CT照片用一个二维数组来存储,假设数组中的每个点代表一个细胞。每个细胞的颜色用0到255之间(包括0和255)的一个整数表示。我们定义一个细胞是异常细胞,如果这个细胞的颜色值比它上下左右4个细胞的颜色值都小50以上(包括50)。数组边缘上的细胞我们不检测。现在我们的任务是,给定一个存储CT照片的二维数组,写程序统计照片中异常细胞的数目。
//
// 输入
//
// 第一行包含一个整数N(100 >= N>2).
//
// 下面有 N 行,每行有 N 个0~255之间的整数,整数之间用空格隔开。
//
// 输出
//
// 输出只有一行,包含一个整数,为异常细胞的数目。
//
// 样例输入
//
// 70 70 70 70
// 70 10 70 70
// 70 70 20 70
// 70 70 70 70
// 样例输出
//
// 2
#include<iostream>
#include<iomanip>
using namespace std;
int main(){
int a[100][100] = { 0 };
int N;
int AbnormalNum = 0;
cin >> N;
for (int i = 0; i < N; i++){
for (int j = 0; j < N; j++){
cin >> a[i][j];
}
}
if (N>2){
for (int i = 1; i < N - 1; i++){
for (int j = 1; j < N - 1; j++){
if ((i>0 && i<(N - 1)) && (j>0 && j < (N - 1)))
{
if (a[i][j] + 50 <= a[i - 1][j] &&
a[i][j] + 50 <= a[i + 1][j] &&
a[i][j] + 50 <= a[i][j - 1] &&
a[i][j] + 50 <= a[i][j + 1])
{
AbnormalNum += 1;
}
}
}
}
cout << AbnormalNum << endl;
}
else{
cout << AbnormalNum << endl;
}
return 0;
}

编程题#6:循环移动

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//编程题#6:循环移动
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 给定一组整数,要求利用数组把这组数保存起来,再利用实现对数组中的数循环移动。假定共有n个整数,则要使前面各数顺序向后移m个位置,并使最后m各数变为最前面的m各数。
//
// 注意,不要用先输出后m个数,再输出前n - m个数的方法实现,也不要用两个数组的方式实现。
//
// 要求只用一个数组的方式实现,一定要保证在输出结果时,输出的顺序和数组中数的顺序是一致的。
//
// 输入
//
// 输入有两行:第一行包含一个正整数n和一个正整数m,第二行包含n个正整数。每两个正整数中间用一个空格分开。
//
// 输出
//
// 输出有一行:经过循环移动后数组中整数的顺序依次输出,每两个整数之间用空格分隔。
//
// 样例输入
//
// 11 4
// 15 3 76 67 84 87 13 67 45 34 45
// 样例输出
//
// 67 45 34 45 15 3 76 67 84 87 13
// 提示
//
// 这是一道经典的算法问题,在企业面试里出现概率很高。除了循环m次每次移动一个数以外(这样需要对数组操作m*n次),你还能想到更高效的算法吗(只用操作3*n次)?依然要求不使用额外数组,在原数组上移位之后顺序输出。
//
#include<iostream>
using namespace std;
int main(){
int n, m;
cin >> n >> m;
int a[10000] = { 0 };
for (int i = 0; i < n-m; i++){
cin >> a[i+m];
}
for (int i = n - m; i < n; i++){
cin >> a[(i + m) % n];
}
for (int i = 0; i < n; i++){
cout << a[i]<<" ";
}
return 0;
}

编程题#7:中位数

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//编程题#7:中位数
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 2000ms 内存限制 : 65536kB
//
// 描述
//
// 中位数定义:一组数据按从小到大的顺序依次排列,处在中间位置的一个数或最中间两个数据的平均值(如果这组数的个数为奇数,则中位数为位于中间位置的那个数;如果这组数的个数为偶数,则中位数是位于中间位置的两个数的平均值).
//
// 给出一组无序整数,求出中位数,如果求最中间两个数的平均数,向下取整即可(不需要使用浮点数)
//
// 输入
//
// 该程序包含多组测试数据,每一组测试数据的第一行为N,代表该组测试数据包含的数据个数,1 <= N <= 15000.
//
// 接着N行为N个数据的输入,N = 0时结束输入
//
// 输出
//
// 输出中位数,每一组测试数据输出一行
//
// 样例输入
//
// 4
// 10
// 30
// 20
// 40
// 3
// 40
// 30
// 50
// 4
// 1
// 2
// 3
// 4
// 0
// 样例输出
//
// 25
// 40
// 2
// 提示
//
// 这是也一道经典的算法问题,在企业面试里出现概率很高,是“找到第K大的数”的变种。先排序再找中位数自然是很直接的做法,但排序本身很慢。我们只想找到第n / 2大的数,对于其他数的顺序我们并不关心。那么怎么在不排序的前提下找到第n / 2大的数呢?
//
#include<iostream>
using namespace std;
int main(){
int N;
int a[15000] = { 0 };
int LessNumber = 0;
int EqualNumber = 0;
while (1){
cin >> N;
if (N != 0){
for (int i = 0; i < N; i++){
cin >> a[i];
}
if (N % 2 == 0){
int m1_index = N / 2 - 1;
int m2_index = N / 2;
int m1 = 0;
int m2 = 0;
for (int i = 0; i < N; i++){
int LessNumber = 0;
int EqualNumber = 0;
for (int j = 0; j < N; j++){
if (a[j] < a[i]){
LessNumber += 1;
}
else if (a[j] == a[i]){
EqualNumber += 1;
}
}
EqualNumber -= 1;
if (LessNumber < m1_index){
if (LessNumber + EqualNumber == m1_index){
m1 = a[i];
}
if (LessNumber + EqualNumber >= m2_index){
cout << a[i];
}
}
else if (LessNumber == m1_index){
m1 = a[i];
if (LessNumber + EqualNumber >= m2_index){
cout << a[i];
}
}
else if (LessNumber == m2_index){
m2 = a[i];
}
}
cout << (m1 + m2) / 2 << endl;
}
else{
int m_index = N / 2;
int m = 0;
for (int i = 0; i < N - 1; i++){
int LessNumber = 0;
int EqualNumber = 0;
for (int j = 0; j < N; j++){
if (a[j] < a[i]){
LessNumber += 1;
}
else if (a[j] == a[i]){
EqualNumber += 1;
}
}
EqualNumber -= 1;
if (LessNumber < m_index){
if (LessNumber + EqualNumber == m_index){
m = a[i];
cout << m << endl;
}
}
else if (LessNumber == m_index){
m = a[i];
cout << m << endl;
}
}
}
}
else
break;
}
return 0;
}

编程题#8:校门外的树

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//编程题#8:校门外的树
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。
//
// 马路上有一些区域要用来建地铁,这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。
//
// 输入
//
// 输入的第一行有两个整数L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。
//
// 输出
//
// 输出包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。
//
// 样例输入
// 第一组
// 500 3
// 150 300
// 100 200
// 470 471
// 第二组
// 500 3
// 100 200
// 150 160
// 180 190
// 样例输出
//
// 第一组
// 298
// 第二组
// 400
// 提示
//
// 由于数据范围不大(L <= 10000),我们可以使用一个10001长度的数组来记录每一个坐标上有没有树。但想象一下如果数据范围很大,比如下面这个情况,你怎么办呢?
//
#include<iostream>
using namespace std;
int main(){
int a[10001] = { 0 };
int L, M;
cin >> L >> M;
for (int i = 0; i <= L; i++){
a[i] = 1;
}
for (int j = 0; j < M; j++){
int left, right;
cin >> left >> right;
for (int k = left; k <= right; k++){
a[k] = 0;
}
}
int counter = 0;
for (int i = 0; i <= L; i++){
if (a[i] == 1){
counter += 1;
}
}
cout << counter << endl;
return 0;
}

Week 11 C程序中的字符串

在能够运用“数组”来解决问题的基础上,再来学习一下“字符串”的特性,在此基础上,我们将讲授C语言的中的“第四种成分”——输入输出成分。 本部分的重点在于:掌握“数组”与“字符串”的区别,理解“输入缓冲区”的基本机理,掌握cin cout的使用技巧。

第一课

字符数组与字符串9 min

输入缓冲区8 min

一个字符的输入11 min

第二课

一串字符的输入22 min

字符串应用例题14 min

写在下一个部分之前的话

写在下一个部分之前的话10 min

Week 12

编程题#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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//编程题#1:判断闰年
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 判断某年是否是闰年。
//
// 输入
//
// 输入只有一行,包含一个整数a(0 < a < 3000)
//
// 输出
//
// 一行,如果公元a年是闰年输出Y,否则输出N
//
// 样例输入
//
// 2006
// 样例输出
//
// N
// 提示
//
// 公历纪年法中,能被4整除的大多是闰年,但能被100整除而不能被400整除的年份不是闰年, 能被3200整除的也不是闰年,如1900年是平年,2000年是闰年,3200年不是闰年。
#include<iostream>
using namespace std;
int main(){
int Year;
cin >> Year;
if (Year % 4 == 0){
if (Year % 100 == 0){
if (Year % 400 == 0){
if (Year % 3200 == 0){
cout << 'N' << endl;
}
else{
cout << 'Y' << endl;
}
//cout << 'Y' << endl;
}
else{
cout << 'N' << endl;
}
}
else{
cout << 'Y' << endl;
}
}
else{
cout << 'N' << endl;
}
return 0;
}

编程题#2:能被3,5,7整除的数

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//编程题#2:能被3,5,7整除的数
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 输入一个整数,判断它能否被3,5,7整除,并输出以下信息:
//
// 1、能同时被3,5,7整除(直接输出3 5 7,每个数中间一个空格);
//
// 2、能被其中两个数整除(输出两个数,小的在前,大的在后。例如:3 5或者 3 7或者5 7, 中间用空格分隔)
//
// 3、能被其中一个数整除(输出这个除数)
//
// 4、不能被任何数整除;(输出小写字符'n', 不包括单引号)
//
// 输入
//
// 一个数字
//
// 输出
//
// 一行数字, 从小到大排列, 包含3, 5, 7中为该输入的除数的数字, 数字中间用空格隔开
//
// 样例输入
//
// 第一组
// 0
// 第二组
// 5
// 第三组
// 15
// 第四组
// 105
// 第五组
// 1
// 样例输出
//
// 第一组
// 3 5 7
// 第二组
// 5
// 第三组
// 3 5
// 第四组
// 3 5 7
// 第五组
// n
// 提示
//
// 因为有多组测试数据, 程序通过下面方式读入n
//
// int n;
//while (cin >> n)
//{
// // 你的代码
// cout << "你的结果" << endl;
//}
//// good luck:)
#include<iostream>
using namespace std;
int main(){
int n;
while (cin >> n)
{
if (n % 3 == 0){
cout << "3 ";
}
if (n % 5 == 0){
cout << "5 ";
}
if (n % 7 == 0){
cout << "7 ";
}
if (n % 3 != 0 && n % 5 != 0 && n % 7 != 0){
cout << 'n';
}
cout << endl;
}
return 0;
}

编程题#3:最远距离

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//编程题#3:最远距离
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 给定一组点(x, y),求距离最远的两个点之间的距离。
//
// 输入
//
// 第一行是点数n(n大于等于2)
//
// 接着每一行代表一个点,由两个浮点数x y组成。
//
// 输出
//
// 输出一行是最远两点之间的距离。
//
// 使用cout << fixed << setprecision(4) << dis << endl; 输出距离值并精确到小数点后4位。
//
// fixed和setprecision是在<iomanip>头文件里定义的格式控制操作符,需要#include <iomanip>.
//
// 样例输入
//
// 34.0 23.0
// 28.1 21.6
// 14.7 17.1
// 17.0 27.2
// 34.7 67.1
// 29.3 65.1
// 样例输出
//
// 53.8516
// 提示
//
// 注意在内部计算时最好使用double类型,float精准度不能满足本题测试数据要求。
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
int main(){
int n;
double a[10000];
cin >> n;
for (int i = 0; i < 2 * n; i = i + 2){
double x, y;
cin >> x >> y;
a[i] = x;
a[i + 1] = y;
}
double MaxDis = 0;
for (int i = 0; i < 2 * n-2; i = i + 2){
for (int j = i + 2; j < 2 * n; j = j + 2){
double dis = sqrt(pow((a[i] - a[j]),2.0) + pow((a[i+1] - a[j+1]),2.0));
MaxDis = dis>MaxDis ? dis : MaxDis;
}
}
cout << MaxDis << endl;
return 0;
}

编程题#4:简单计算器

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//编程题#4:简单计算器
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
//
// 一个最简单的计算器,支持 + , -, *, / 四种运算。仅需考虑输入输出为整数的情况,数据和运算结果不会超过int表示的范围。
//
// 输入
//
// 输入只有一行,共有三个参数,其中第1、2个参数为整数,第3个参数为操作符( + , -, *, / )。
//
// 输出
//
// 输出只有一行,一个整数,为运算结果。然而:
//
// 1. 如果出现除数为0的情况,则输出:Divided by zero!
//
// 2. 如果出现无效的操作符(即不为 + , -, *, / 之一),则输出:Invalid operator!
//
// 样例输入
//
// 第一组
// 1 2 +
// 第二组
// 1 0 /
// 第三组
// 1 0 XOR
// 样例输出
//
// 第一组
// 3
// 第二组
// Divided by zero!
// 第三组
// Invalid operator!
// 提示
//
// 可以考虑使用if和switch结构。
#include<iostream>
using namespace std;
int main(){
int a, b;
char ch[1000];
cin >> a >> b >> ch;
if (ch[0] == '+' && ch[1]=='\0'){ cout << a + b << endl; }
else if (ch[0] == '-' && ch[1] == '\0'){ cout << a - b << endl; }
else if (ch[0] == '*' && ch[1] == '\0'){ cout << a * b << endl; }
else if (ch[0] == '/' && ch[1] == '\0'){
if (b == 0){
cout << "Divided by zero!" << endl;
}
else{
cout << a / b << endl;
}
}
else{
cout << "Invalid operator!" << endl;
}
return 0;
}

编程题#5:字符串插入

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//编程题#5:字符串插入
//
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB、
//
// 描述
//
// 有两个字符串str和substr,str的字符个数不超过10,substr的字符个数为3。(字符个数不包括字符串结尾处的'\0'。)将substr插入到str中ASCII码最大的那个字符后面,若有多个最大则只考虑第一个。
//
// 输入
//
// 输入包括若干行,每一行为一组测试数据,格式为
//
// str substr
//
// 输出
//
// 对于每一组测试数据,输出插入之后的字符串。
//
// 样例输入
//
// abcab eee
// 12343 555
// 样例输出
//
// abceeeab
// 12345553
// 提示
//
// 这题有多组输入,请参照第二题的提示依次读入和处理每一组数据。
//
// 如果使用了字符串函数,比如strlen,请包含cstring头文件 #include <cstring>。
#include<iostream>
using namespace std;
int main(){
char str[11] = "";
char substr[4] = "";
char result[15] = "";
while (cin >> str >> substr){
int l_str = 0;
int l_substr = 0;
int max_index = 0;
int max_str = 0;
//1. l_str:
// calculate length of str.
//2. max_index:
// find out the index of the max value of ASCII in str.
for (int i = 0; i < 11; i++){
if (str[i] == '\0'){
break;
}
if (str[i]>max_str){
max_index = i;
max_str = str[i];
}
l_str += 1;
}
//1. l_substr:
// calculate length of substr.
for (int i = 0; i < 4; i++){
if (substr[i] == '\0'){
break;
}
l_substr += 1;
}
//insert the value in str before max_index
for (int i = 0; i <= max_index; i++){
result[i] = str[i];
}
//insert the value in substr
for (int i = max_index + 1; i <= max_index + l_substr; i++){
result[i] = substr[i - max_index-1];
}
//insert the value in str after max_index
for (int i = max_index + l_substr+1; i < l_str + l_substr; i++){
result[i] = str[i - l_substr];
}
cout << result << endl;
}
return 0;
}

C程序设计进阶

Lecture slides can be found [here]
Coursera can be found here

About this course: 如果说学习过《计算导论与C语言基础》,你已经迈入了C语言的殿堂,那么《C程序设计进阶》将帮助你更上一层楼,理解“结构化程序设计的基本思想”,掌握“C程序设计的基本技巧”,养成“良好的编程习惯和编程风格”,编写出“真正具有生命力的计算机程序”。完成这门课的学习,你将能解释C程序设计语言的基本概念与知识,并且使用C语言编写计算机程序解决生活工作中的实际问题。

Week 1 欢迎加入《C程序设计进阶》

在学习完“理性认识C程序”之后,我们希望同学们能够自己动手编写一些简单的C程序了!如果你还没有具备这个能力,一个可能的原因是因为你还没有进行“足够的训练”。因为,学习一门程序语言,需要你获得的有两样东西——“知识”和“技巧”。“知识”可以通过讲授传递,但“技巧”却只能通过训练获得。因此,我们鼓励同学们在“理性认识C程序”这个迭代周期中,多多进行简单的编程练习,以便获得“技巧”。(注意:我们特别鼓励同学们多多进行“简单”的编程练习,因为,所有复杂的问题,都是简单问题的组合。我们的教学实践表明:多做简单练习,不但可以提升学习者的学习信心,也非常有助于编程技巧的提升!)在完成“理性认识C程序”部分的学习之后,我们将开始新的迭代周期——“结构化的程序”。在这个部分,我们将讲授一种基本的、用于将程序组织成“模块”的语言成分——函数。函数实际上是C程序的基本组织单位,是C程序设计中的重要组成部分。在这个迭代周期中,同学们不仅要学习函数的定义方式、调用方式,还要学习一种重要的函数使用方法——递归。我们将讲授递归调用的基本机理,并讲授“利用递归解决问题的技巧”。这部分,讲本课程C程序设计部分的一个难点!不过,请同学们不要担心,我们将力图通过最简明的讲解方式,帮助大家掌握“递归”的使用方法,力争“化困难于无形”。我们一起努力吧!PS:我们这门课程一直处在不断地建设与优化当中,吸取了很多以往课程的经典视频,所以如果你看到视频中出现了不同课程的名字,也不要惊讶哦,因为你正在集百家所长。

THE SPECIALIZATION

专项课程介绍2 min

课程介绍

欢迎加入《C程序设计进阶》1 min

Week 2 C程序中的函数

本次课,我们讲授“函数”的基本概念、定义方式、调用方式、参数传递方式等基本知识。其间,我们还将讨论“变量的作用域”的问题。PS:我们这门课程一直处在不断地建设与优化当中,吸取了很多以往课程的经典视频,所以如果你看到视频中出现了不同课程的名字,也不要惊讶哦,因为你正在集百家所长:)

第一课

函数的定义与声明28 min

第二课

函数的调用过程11 min

函数调用示例10 min

第二课

变量的作用域17 min

数组做函数参数14 min

第三课

函数应用示例13 min

编程作业

Programming Assignment: 综合编程练习(1)3h

编程题#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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//编程题#1:寻找下标
//注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
//描述
//已知一个整数数组x[], 其中的元素彼此都不相同。找出给定的数组中是否有一个元素满足x[i] = i的关系,数组下标从0开始。
//
//举例而言,如果x[] = { -2, -1, 7, 3, 0, 8 }, 则x[3] = 3, 因此3就是答案。
//
//输入
//第一行包含一个整数n(0 < n < 100),表示数组中元素的个数。<br / >第二行包含n个整数,依次表示数组中的元素。
//
//输出
//输出为一个整数,即满足x[i] = i的元素,若有多个元素满足,输出第一个满足的元素。若没有元素满足,则输出“N”。
//
//样例输入
//
//第一组
//6
//- 2 - 1 7 3 4 8
//第二组
//6
//9 9 9 9 9 9
//
//样例输出
//
//第一组
//3
//第二组
//N
#include<iostream>
using namespace std;
int main(){
int num;
cin >> num;
int a[100] = { 0 };
for (int i = 0; i < num; i++){
cin >> a[i];
if (i == a[i]){
cout << i << endl;
return 0;
}
}
cout << "N" << endl;
return 0;
}

编程题#2:四大湖

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//编程题#2:四大湖
//注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
//描述
//我国有4大淡水湖。
//
//A说:洞庭湖最大,洪泽湖最小,鄱阳湖第三。
//
//B说:洪泽湖最大,洞庭湖最小,鄱阳湖第二,太湖第三。
//
//C说:洪泽湖最小,洞庭湖第三。
//
//D说:鄱阳湖最大,太湖最小,洪泽湖第二,洞庭湖第三。
//
//已知这4个湖的大小均不相等,4个人每人仅答对一个,
//
//请编程按照鄱阳湖、洞庭湖、太湖、洪泽湖的顺序给出他们的大小排名。
//
//输入
//无。
//
//输出
//输出为4行,第1行为鄱阳湖的大小名次,从大到小名次分别表示为1、2、3、4;第2、3、4行分别为洞庭湖、太湖、洪泽湖的大小名次。
//
//样例输入
//
//(无)
//样例输出
//
//3(样例输出仅供格式参考,此题只有一个解, 。)
#include<iostream>
using namespace std;
int main(){
for (int by = 1; by < 5; by++){
for (int dt = 1; dt < 5; dt++){
if (dt == by){
continue;
}
for (int th = 1; th < 5; th++){
if ((th == dt) || (th == by)){
continue;
}
for (int hz = 1; hz < 5; hz++){
if ((hz == th) || (hz == dt) || (hz == by)){
continue;
}
int a = (dt == 1) + (hz == 4) + (by == 3);
int b = (hz == 1) + (dt == 4) + (by == 2) + (th == 3);
int c = (hz == 4) + (dt == 3);
int d = (by == 1) + (th == 4) + (hz == 2) + (dt == 3);
int judge = (a == 1) + (b == 1) + (c == 1) + (d == 1);
if (judge==4){
cout << by << '\n' << dt << '\n' << th << '\n' << hz << '\n';
return 0;
}
}
}
}
}
}

编程题#3:发票统计

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//编程题#3:发票统计
//注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
//描述
//有一个小型的报账系统,它有如下功能:
//
//(1)统计每个人所报发票的总钱数
//
//(2)统计每类发票的总钱数
//
//将此系统简化为如下:假设发票类别共有A、B、C三种; 一共有三个人,ID分别为1、2、3。
//
//输入
//系统输入包含三行,每行第一个数为人员ID(整型,1或2或3),第二个数为发票总张数(张数不超过100),之后是多个发票类别(字符型,A或B或C)和相应发票金额(单进度浮点型, 不超过1000.0)。
//
//输出
//输出包含六行,前三行为每人(按ID由小到大输出)所报发票总钱数(保留两位小数),后三行为每类发票的总钱数(保留两位小数)。
//
//样例输入
//1 5 A 1.0 A 2.0 C 1.0 B 1.0 C 1
//3 3 B 1 C 2 C 1
//2 4 B 1 A 1 C 1 A 1
//样例输出
//1 6.00
//2 4.00
//3 4.00
//A 5.00
//B 3.00
//C 6.00
#include<iostream>
#include<iomanip>
using namespace std;
int main(){
int id[3] = { 0 };
int num[3] = { 0 };
char type[3][100];
float money[3][100] = { 0 };
float result[6] = { 0 };
//get the input
for (int i = 0; i < 3; i++){
cin >> id[i] >> num[i];
for (int j = 0; j < num[i]; j++){
cin >> type[i][j] >> money[i][j];
}
}
//sum the money with the same id,123
for (int i = 0; i < 3; i++){
int tem_money = 0;
for (int j = 0; j < num[i]; j++){
tem_money += money[i][j];
}
result[id[i] - 1] = tem_money;
}
//sum the money with the same type,ABC
int a = 0;
int b = 0;
int c = 0;
for (int i = 0; i < 3; i++){
for (int j = 0; j < num[i]; j++){
if (type[i][j] == 'A'){
a += money[i][j];
}
else if (type[i][j] == 'B'){
b += money[i][j];
}
else{
c += money[i][j];
}
}
}
result[3] = a;
result[4] = b;
result[5] = c;
//print
char abc[3] = { 'A', 'B', 'C' };
for (int i = 0; i < 6; i++){
if (i < 3){
cout << i+1 << ' ' << fixed<<setprecision(2)<<result[i] << endl;
}
else{
cout << abc[i - 3] << ' ' << fixed<<setprecision(2) << result[i] << endl;
}
}
return 0;
}

编程题#4:Tomorrow never knows?

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//编程题#4:Tomorrow never knows?
//来源 : POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)
//
// 注意: 总时间限制 : 1000ms 内存限制 : 65536kB
//
// 描述
// 甲壳虫的《A day in the life》和《Tomorrow never knows》脍炙人口,如果告诉你a day in the life, 真的会是tomorrow never knows ? 相信学了计概之后这个不会是难题,现在就来实现吧。
//
// 读入一个格式为yyyy - mm - dd的日期(即年-月-日),输出这个日期下一天的日期。可以假定输入的日期不早于1600 - 01 - 01,也不晚于2999 - 12 - 30。
//
// 输入
// 输入仅一行,格式为yyyy - mm - dd的日期。
//
// 输出
// 输出也仅一行,格式为yyyy - mm - dd的日期
//
// 样例输入
//
// 2010 - 07 - 05
// 样例输出
//
// 2010 - 07 - 06
// 提示
// 闰年的标准:
//
// (1)普通年能被4整除且不能被100整除的为闰年。(如2004年就是闰年, 1901年不是闰年)
//
// (2)世纪年能被400整除的是闰年。(如2000年是闰年,1100年不是闰年)
//
// 可以利用一个字符变量吃掉输入的短横线(减号),输出时请活用setfill和setw 控制符。
#include<iostream>
#include<iomanip>
using namespace std;
int leapyearday[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int normyearday[12] = { 31, 22, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
bool leapyear(int year){
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)){
return true;
}
else
return false;
}
int main(){
char minus;
int year, month, day;
cin >> year >> minus >> month >> minus >> day;
int ryear, rmonth, rday;
bool year_is_leap = leapyear(year);
//calculate day
if (year_is_leap){
rday = day % leapyearday[month - 1]+1;
}
else{
rday = day % normyearday[month - 1]+1;
}
//calculate month
if (rday == 1){
rmonth = month%12 + 1;
}
else{
rmonth = month;
}
//calcualte year
if (rmonth == 1){
ryear = year + 1;
}
else{
ryear = year;
}
cout << ryear << minus << setfill('0') << setw(2) << rmonth << minus << setfill('0') << setw(2) << rday << endl;
return 0;
}

Week

primary

Week

primary

Week

primary

Week

primary

Week

primary

Week

primary

Week

primary

#

Lecture slides can be found [here]
Coursera can be found here


primary

#

Lecture slides can be found [here]
Coursera can be found here


primary

#

Lecture slides can be found [here]
Coursera can be found here


primary